본문 바로가기

JavaScript

4장. 데이터 구조: 객체와 배열

숫자, 부울 , 문자열 은 데이터 구조 에서 내장 된 벽돌 입니다. 하지만 당신은 하나의 벽돌 에서 많은 수의 집을 만들수 없습니다. 객체는 그룹 값들과 함께 더 복잡한 데이터 구조를 만들수 있습니다.

   

우리가 구축한 프로그램은 지금까지 단순 데이터 유형에서만 동작하고 있다는 사실에 의해서 방해를 받았습니다.

   

이 장에서는 툴킷에 데이터 구조에 대한 기본적인 이해를 추가 할 것입니다.

이 장의 끝에서 당신은 몇가지 유용한 프로그램을 충분히 이해하고 사용 할 수 있습니다.

이 장에서는 다소 현실적인 프로그램을 통해 동작할 것입니다.

   

예제코드는 이전의 텍스트에서 function과 변수를 활용 할 것입니다.

   

- The Weresquirrel

   

8시에서 10 사이에 자크는 덥수룩한 털과 함께 작은 모피 설치류로 변하고 있다는 것을 알았다. 한편 자크는 자신이 늑대인간으로 변하지는 않을 것을 다행이라 생각했다.

다람쥐로 변하게 되면 늑대인간으로 변하는 것보다 문제가 발생하는 경향이 있다.

이웃들을 잡아먹는 사고 등에 대한 걱정 대신, 그는 이웃들의 고양이에게 먹히는걸 걱정했다

그는 오크나무에서 벌거벗은채로 깨어 그의방과 문을 걸어잠그고 바닥에 호두를 넣기 바빴다. 그가 오크나무를 만질때 마다 변신한다. 그래서 그는 나무를 터치하는 것을 멈추었지만 문제는 여전했다.

과학적으로 접근해서 자크는 매일 모든것에 로그를 남기는 것을 시작했다 그의 변화에 대해 이 데이터는 그가 변화하는 때를 좁혀 줄것이라고 희망한다. 그는 첫번째로 데이터 구조를 디자인 했다.

   

- Data Sets

디지털 데이터가 작동하려면 우리의 기계의 메모리에서 표현하는 방법을 알아야 한다. 예를들어 말하자면 2,3,5,7,그리고11의 numbers 집합을 표현하기를 원한다.

우리는 문자열을 창조적으로 얻은 후에 문자열은 어떠한 길이도 될수있습니다.

우리는 많은 문자열 데이터를 넣을 수 있고, 그리고 2,3,4,5,11이라는 우리의 표현을 사용할 수있습니다. 그러나 이것은 어색합니다. 당신은 어떻게든 숫자를 추출해야 할것이고 그것들에 접근하기 위해 다시 변환해야만 할것입니다.

운이 좋게도 자바스크립트는 특별하게 값들의 순서를 저장하기 위한 데이터 타입을 지원합니다. 배열 (array)라고 합니다. 이것은 대괄호 안에 리스트로서 쓰여지고 콤마( , )로 분리 됩니다.

   

var listOfNumbers = [2, 3, 5, 7, 11];

console.log(listOfNumbers[1]);

// . 3

console.log(listOfNumbers[1 - 1]);

// . 2

   

  • Properties

   

우리는 이전 예제들에서 몇가지 myString.length,Math.max 같은 몇가지 의심스러운 표현들을 살펴 보았다.몇가지 value 속성으로 접근하는 표현들이 있다. 첫번째로 우리는 myString 에서 lnegth속성으로 접근한다. 번째로는 Math객체 안에 max 불리우는 속성으로 접근한다. (이것은 수학과 연관된 value function 관련이 있다. )

대게 모든 자바스크립트 속성들은 properties(속성) 가진다. 예외는 null, undefined이다. 만약에 이러한 nonvalues 접근하려 한다면, 에러를 얻는다.

   

null.length;

// . TypeError: Cannot read property 'length' of null

   

자바스크립트에서 속성들에 접근하기 위한 두가지 일반적인 방법 dot(마침표) 대괄호([ ])이다. value.x 그리고 value[x] value 접근한다. 그러나 필수적으로 같은 속성이라고 없다. 차이점은 x 사용하는 방법에 의해 해석된다. Dot(마침표) 사용할때는 마침표 이후의 부분은 유효한 변수여야 한다. 직접적으로 이름을 사용한다.

대괄호를 사용하는 경우 괄호 사이의 표현은 속성이름을 얻기위해 사용된다.

다시말해 value.x 속성의 값을 가져오는 반명, value[x] 속성이름을 결과로 사용한다. 그래서 당신이 속성을 알기 원한다면 "length" 사용하라. 만약 너가 변수1 값을 추출하기를 원한다면 value[1] 사용하라. 그리고 속성은 어떤 문자열도 사용할 수있다. 너가 "o","Jogn Doe" 접근한다면 너는 대괄호를 사용해야한다. Value[0],혹은 value["John Doe"] 같이 .

   

- Method

   

흥미롭게도 toUpperCase 대해 인수를 전달하지 않는 경우에도 함수는 어떻게든 문자열"Doh" 호출 하여 접근합니다. 이것이 어떻게 동작하는지는 6장에서 설명합니다. 함수(function) 포함하는 속성은 value 포함하는 메소드라고 합니다.

마찬가지로 toUppercase 문자열의 메소드입니다.

   

다음 예제는 배열 객체들이 가지는 몇가지 메소드의 예제입니다.

   

The push method can be used to add values to the end of an array. The

pop method does the opposite: it removes the value at the end of the array

and returns it. An array of strings can be flattened to a single string with the

join method. The argument given to join determines the text that is glued

between the array's elements.

push 메소드는 배열의 최종값을 추가 하기 위해 사용된다.

Pup메소드는 반대로 마지막 값을 제거하고 그것을 return한다.

배열의 문자들을 단일 문자열로 바꿔주는 메소드는 join메소드이다.

주어진 인자들은 배열 요소들 사이에 text 이어 붙여 준다.

   

Objects

Back to the weresquirrel. A set of daily log entries can be represented as an

array. But the entries do not consist of just a number or a string—each entry

needs to store a list of activities and a Boolean value that indicates whether

Jacques turned into a squirrel. Ideally, we would like to group these values

together into a single value and then put these grouped values into an array

of log entries.

   

객체

객체는 Number ,문자 , 부울린 이러한 값들을 포함하는 것을 그룹화하는 것이다.

이러한 객체의 속성값은 임의로 추가하거나 제거할 수있다.

객체의 생성 방법은 중괄호를 사용하는 것이다.

   

var day1 = {

squirrel: false,

events: ["work", "touched tree", "pizza", "running",

"television"]

};

console.log(day1.squirrel);

// . false

console.log(day1.wolf);

// . undefined

day1.wolf = false;

console.log(day1.wolf);

// . false

Inside the braces, we can give a list of properties separated by commas.

Each property is written as a name, followed by a colon, followed by an expression

that provides a value for the property. Spaces and line breaks are

not significant. When an object spans multiple lines, indenting it like in

the previous example improves readability. Properties whose names are not

valid variable names or valid numbers have to be quoted.

   

중괄호 내부에서, 우리는 쉼표로 구분된 속성의 목록을 보여준다.

속성은 쉼표로 구분한다.

공백과 줄바꿈은 중요하다. 객체가 들여쓰기, 여러 줄에 걸쳐 사용된다. 이렇게 사용하면 가독성을 높일 있다.

var descriptions = {

work: "Went to work",

"touched tree": "Touched a tree"

};

This means that braces have two meanings in JavaScript. At the start of

a statement, they start a block of statements. In any other position, they describe

an object. Fortunately, it is almost never useful to start a statement

with a brace object, and in typical programs, there is no ambiguity between

Reading a property that doesn't exist will produce the value undefined,

which happens the first time we try to read the wolf property in the previous

example.

   

중괄호는 자바스크립트에서 두가지 의미를 가진다.

문장의 시작을 표시하는 동시에 다른의미에서는 객체를 묘사하는 의미를 가진다.

   

   

It is possible to assign a value to a property expression with the = operator.

This will replace the property's value if it already existed or create a new

property on the object if it didn't.

To briefly return to our tentacle model of variable bindings—property

bindings are similar. They grasp values, but other variables and properties

might be holding onto those same values. You may think of objects as octopuses

with any number of tentacles, each of which has a name inscribed

on it.

   

"="연산자 속성식에 값을 할당 수있다. 이것은 이미 존재하는 경우 속성값을 대체하거나 새로 만든다.

The delete operator cuts off a tentacle from such an octopus. It is a

unary operator that, when applied to a property access expression, will remove

the named property from the object. This is not a common thing to

do, but it is possible.

   

Delete 연산자는 객체의 속성을 제거한다.

일반적으로 사용되진 않지만 가능하다.

var anObject = {left: 1, right: 2};

console.log(anObject.left);

// . 1

delete anObject.left;

console.log(anObject.left);

// . undefined

console.log("left" in anObject);

// . false

console.log("right" in anObject);

// . true

The binary in operator, when applied to a string and an object, returns

a Boolean value that indicates whether that object has that property. The

difference between setting a property to undefined and actually deleting it is

that, in the first case, the object still has the property (it just doesn't have a

very interesting value), whereas in the second case the property is no longer

present and in will return false.

   

"in" 연산자는 그것의 속성이 존재하는지 boolean 값으로 리턴한다.

   

Arrays, then, are just a kind of object specialized for storing sequences

of things. If you evaluate typeof [1, 2], this produces "object". You can see

64 Chapter 4

them as long, flat octopuses with all their arms in a neat row, labeled with

numbers.

배열은 시퀀스를 저장하기 위한 특별한 개체 종류중 하나이다. 만약 typeof [1,2] 실행해 본다면 "object" 된다.

   

So we can represent Jacques's journal as an array of objects.

var journal = [

{events: ["work", "touched tree", "pizza",

"running", "television"],

squirrel: false},

{events: ["work", "ice cream", "cauliflower",

"lasagna", "touched tree", "brushed teeth"],

squirrel: false},

{events: ["weekend", "cycling", "break",

"peanuts", "beer"],

squirrel: true},

/* and so on... */

];

Mutability

가변성

We will get to actual programming real soon now. But first, there's one last

piece of theory to understand.

   

We've seen that object values can be modified. The types of values discussed

in earlier chapters, such as numbers, strings, and Booleans, are all

immutable—it is impossible to change an existing value of those types. You

can combine them and derive new values from them, but when you take a

specific string value, that value will always remain the same. The text inside

it cannot be changed. If you have reference to a string that contains "cat", it

is not possible for other code to change a character in that string to make it

spell "rat".

   

객체의 값은 수정될 있다. numbers,strings,Booleans 이미 존재하는 타입의 값을 변경하는 것은 불가능 하다. 결합하여 새로운 값을 만드는 것은 가능하지만, 특정 문자열 값은 항상 동일하게 유지된다. 만약"cat" 포함하는 문자열에 대한 다른 참조가 있으면 다른 ㅗ드를 만들기 위해 해당 문자열의 변경은 수없다.

With objects, on the other hand, the content of a value can be modified

by changing its properties.

When we have two numbers, 120 and 120, we can consider them precisely

the same number, whether or not they refer to the same physical bits.

But with objects, there is a difference between having two references to the

Data Structures:

same object and having two different objects that contain the same properties.

Consider the following code:

   

다른 한편으로는 객체의 내용은 수정이 수있 .

해당 속성을 변경하여 숫자 120 120 가질때 , 것들이 정확하게 같은 숫자인지 생각해볼 필요가 있다. 여기 차이점이 있다 두개의 참조를 가지는 데이터 구조가

하나는 같은 객체 하나는 두가지 다른객체를 가지지만 같은 속성을 가지고 있다.

   

var object1 = {value: 10};

var object2 = object1;

var object3 = {value: 10};

console.log(object1 == object2);

// . true

console.log(object1 == object3);

// . false

object1.value = 15;

console.log(object2.value);

// . 15

console.log(object3.value);

// . 10

The object1 and object2 variables grasp the same object, which is why

changing object1 also changes the value of object2. The variable object3 points

to a different object, which initially contains the same properties as object1

but lives a separate life.

   

object1 object2 는 같은객체이다. object1 변경하면 object2 값이 변경된다.

하지만 object3 다른객체이다. 속성은 같지만 object1과는 별도이다.

JavaScript's == operator, when comparing objects, will return true only if

both objects are precisely the same value. Comparing different objects will

return false, even if they have identical contents. There is no deep comparison

operation built into JavaScript, which looks at object's contents, but it is

possible to write it yourself (which will be one of the exercises at the end of

this chapter).

   

자바스클립트의 "=="연산자는 객체를 비교할때 객체가 정확하게 같은 객체여야 true return 한다. 다른 객체를 비교하면 동일한 내용을 가지고 있더라도 false 리턴한다. 자바스크립트는 객체의 내용 까지 깊이 비교하는 것이 내장되어 있지 않다. 그러나 이장의 끝에서 비교하는 법을 연습한다.

Further Arrayology

Before finishing up this chapter, I want to introduce you to a few more

object-related concepts. We'll start by introducing some generally useful

array methods.

장을 마무리하기 전에 몇가지 객체관련 개념을 소개한다.

   

We saw push and pop, which add and remove elements at the end of an

array, earlier in this chapter. The corresponding methods for adding and

removing things at the start of an array are called unshift and shift.

   

Push ,pop 이외에 unshift shift 있다.

var todoList = [];

function rememberTo(task) {

todoList.push(task);

}

function whatIsNext() {

return todoList.shift();

}

function urgentlyRememberTo(task) {

todoList.unshift(task);

}

The previous program manages lists of tasks. You add tasks to the end of

the list by calling rememberTo("eat"), and when you're ready to do something,

you call whatIsNext() to get (and remove) the front item from the list. The

urgentlyRememberTo function also adds a task but adds it to the front instead of

the

   

이 프로그램은 작업목록을 관리한다. rememberTo("eat")를 호출하면 배열에 저장한다. 그리고 whatIsNext()를 호출하면 리스트 제일 앞에 아이템을 가져온다. urgentlyRememberTo 함수는 배열의 마지막에 오지않고 제일 앞에 오게 된다.

   

The indexOf method has a sibling called lastIndexof, which starts searching

for the given element at the end of the array instead of the front.

indexOf 메소드와 형제로 불리우는 lastIndexof 주어진 요소의 위치를 반환한다.

   

   

   

console.log([1, 2, 3, 2, 1].indexOf(2));

// . 1

console.log([1, 2, 3, 2, 1].lastIndexOf(2));

// . 3

Both indexOf and lastIndexOf take an optional second argument that indicates

where to start searching from.

   

indexOf lastIndexOf 선택적으로 찾는 시작점을 지정할 수있는 두번째 인자를 가진다.

Another fundamental method is slice, which takes a start index and an

end index and returns an array that has only the elements between those

indices. The start index is inclusive, the end index exclusive.

   

다른 메소드인 slice 시작 인덱스부터 인덱스 안에 모든 요소를 가져온다. 리턴된 배열은 오직 범위 안에 요소들이다. 시작 인덱스는 포함하지만 끝 인덱스는 포함하지 않는다.

console.log([0, 1, 2, 3, 4].slice(2, 4));

// . [2, 3]

console.log([0, 1, 2, 3, 4].slice(2));

// . [2, 3, 4]

When the end index is not given, slice will take all of the elements after

the start index. Strings also have a slice method, which has a similar effect.

   

인덱스가 주어지지 않으면, slice메소드는 시작점 이후 모든 인덱스를 가져온다. 문자열 또한 slice메소드와 비슷한 것을 가진다. Concat 메소드는 배열을 합칠 있다. 다음 예제는 concat slice에제이다.

The concat method can be used to glue arrays together, similar to what

the + operator does for strings. The following example shows both concat

and slice in action. It takes an array and an index, and it returns a new array

that is a copy of the original array with the element at the given index

removed.

   

Concat 메소드는 배열을 합칠 있다. 다음 예제는 concat slice에제이다.

   

function remove(array, index) {

return array.slice(0, index)

.concat(array.slice(index + 1));

}

console.log(remove(["a", "b", "c", "d", "e"], 2));

// . ["a", "b", "d", "e"]

   

   

Strings and Their Properties

   

   

We can read properties like length and toUpperCase from string values. But if

you try to add a new property, it doesn't stick.

우리는 length toUppercase 문자열 값으로 부터 읽을 수있다. 그러나 새로운 속성을 추가 하려한다면 그것은 정의 되지 않은 것이기 때문에 undefined 이다.

   

   

   

var myString = "Fido";

myString.myProperty = "value";

console.log(myString.myProperty);

doesn't actually store those properties. The values are immutable and cannot

be changed.

But these types do have some built-in properties. Every string value has

a number of methods. The most useful ones are probably slice and indexOf,

which resemble the array methods of the same name.

console.log("coconuts".slice(4, 7));

// . nut

console.log("coconut".indexOf("u"));

// . 5

그러나 이러한 타입들은 몇가지 특성을 가진다. 모든 문자열은 메소드를 가진다. 가장 유용한 것은 slice indexOf,이것은 배열 메소드와 유사하다.

   

   

One difference is that a string's indexOf can take a string containing

more than one character, whereas the corresponding array method looks

only for a single element.

   

   

한가지 차이점은 문자열의 indexOf 문자를 두개 이상 취할수 있는 반면 array메소드는 한개의 요소만 취할 수있다.

console.log("one two three".indexOf("ee"));

// . 11

   

   

The trim method removes whitespace (spaces, newlines, tabs, and similar

characters) from the start and end of a string.

   

trim 메소드는 공백을 제거한다. (공백들,줄바꿈, tabs, 유사 characters) 시작과 끝의 문자열로 부터

   

console.log(" okay \n ".trim());

// . okay

We have already seen the string type's length property. Accessing the

individual characters in a string can be done with the charAt method but also

by simply reading numeric properties, like you'd do for an array.

문자타입의 length 속성을 이미 보았다. 개별 문자로 접근하는 것은 charAt메소드 뿐만 아니라 단순하게 numeric 속성으로 (value.x ) 같이 접근 수있다.

   

   

   

var string = "abc";

console.log(string.length);

// . 3

console.log(string.charAt(0));

// . a

console.log(string[1]);

// . B

   

   

The arguments Object

   

Whenever a function is called, a special variable named arguments is added

to the environment in which the function body runs. This variable refers to

an object that holds all of the arguments passed to the function. Remember

that in JavaScript you are allowed to pass more (or fewer) arguments to a

function than the function threeArguments(a, b, c) {} threeArguments(); // And so is this

The arguments object has a length property that tells us the number of

arguments that were really passed to the function. It also has a property for

each argument, named 0, 1, 2, and so on.

If that sounds a lot like an array to you, you're right, it is a lot like an

array. But this object, unfortunately, does not have any array methods (like

slice or indexOf), so it is a little harder to use than a real array.

   

함수가 호출 때마다 특수한 가변인자는 함수 본문이 실행되는 환경에서 추가된다.

변수는 함수에 전달된 모든 인수를 보유하고 객체를 참조한다. 자바스크립트에서 매개 변수의 수보다 기능자체가 선언하는 인수를 전달하도록 하는것을 명심해라.

   

function argumentCounter() {

console.log("You gave me", arguments.length, "arguments.");

}

argumentCounter("Straw man", "Tautology", "Ad hominem");

// . You gave me 3 arguments.

Some functions can take any number of arguments, like console.log.

These typically loop over the values in their arguments object. They can be

used to create very pleasant interfaces. For example, remember how we

created the entries to Jacques's journal.

addEntry(["work", "touched tree", "pizza", "running",

"television"], false);

Since he is going to be calling this function a lot, we could create an alternative

that is easier to call.

function addEntry(squirrel) {

var entry = {events: [], squirrel: squirrel};

for (var i = 1; i < arguments.length; i++)

entry.events.push(arguments[i]);

journal.push(entry);

}

addEntry(true, "work", "touched tree", "pizza",

"running", "television");

This version reads its first argument (squirrel) in the normal way and

then goes over the rest of the arguments (the loop starts at index 1, skipping

the first) to gather them into an array.

   

자주사용하는 객체는 이런식으로 구현할수도 있다.

   

   

The Math Object

As we've seen, Math is a grab-bag of number-related utility functions, such as

Math.max (maximum), Math.min (minimum), and Math.sqrt (square root).

다음과 같은 Math기능을 제공한다.

Math.max (maximum), Math.min (minimum), and Math.sqrt (square root).

   

The Math object

a value. Rather, it provides a namespace so that all these functions and values

do not have to be global variables.

Having too many global variables "pollutes" the namespace. The more

names that have been taken, the more likely you are to accidentally overwrite

the value of some variable. For example, it's not unlikely that you'll

want to name something max in one of your programs. Since JavaScript's

built-in max function is tucked safely inside the Math object, we don't have to

worry about overwriting it.

Many languages will stop you, or at least warn you, when you are defining

a variable with a name that is already taken. JavaScript does neither, so

be careful.

Back to the Math object. If you need to do trigonometry, Math can help.

It contains cos (cosine), sin (sine), and tan (tangent), as well as their inverse

functions, acos, asin, and atan, respectively. The number (pi)—or at least

the closest approximation that fits in a JavaScript number—is available as

Math.PI. (There is an old programming tradition of writing the names of constant

values in all caps.)

function randomPointOnCircle(radius) {

var angle = Math.random() * 2 * Math.PI;

return {x: radius * Math.cos(angle),

y: radius * Math.sin(angle)};

}

console.log(randomPointOnCircle(2));

// . {x: 0.3667, y: 1.966}

If sines and cosines are not something you are very familiar with, don't

worry. When they are used in this book, in Chapter 13, I'll explain them.

The previous example uses Math.random. This is a function that returns a

new pseudorandom number between zero (inclusive) and one (exclusive)

every time you call it.

console.log(Math.random());

// . 0.36993729369714856

console.log(Math.random());

// . 0.727367032552138

console.log(Math.random());

// . 0.40180766698904335

Though computers are deterministic machines—they always react the

same way if given the same input—it is possible to have them produce numbers

that appear random. To do this, the machine keeps a number (or a

bunch of numbers) in its internal state. Then, every time a random number

is requested, it performs some complicated deterministic computations on

this internal state and returns part of the result of those computations. The

machine also uses the outcome to change its own internal state so that the

next "random" number

If we want a whole random number instead of a fractional one, we can

use Math.floor (which rounds down to the nearest whole number) on the

result of Math.random.

console.log(Math.floor(Math.random() * 10));

// . 2

Multiplying the random number by 10 gives us a number greater than

or equal to zero, and below 10. Since Math.floor rounds down, this expression

will produce, with equal chance, any number from 0 through 9.

There are also the functions Math.ceil (for "ceiling," which rounds up to

a whole number) and Math.round (to the nearest whole number).

The Global Object

The global scope, the space in which global variables live, can also be approached

as an object in JavaScript. Each global variable is present as a property

of this object. In browsers, the global scope object is stored in the window

variable.

var myVar = 10;

console.log("myVar" in window);

// . true

console.log(window.myVar);

// . 10

Summary

Objects and arrays (which are a specific kind of object) provide ways to group

several values into a single value. Conceptually, this allows us to put a bunch

of related things in a bag and run around with the bag, instead of trying to

wrap our arms around all of the individual things and trying to hold on to

them separately.

Most values in JavaScript have properties, the exceptions being null and

undefined. Properties are accessed using value.propName or value["propName"].

Objects tend to use names for their properties and store more or less a fixed

set of them. Arrays, on the other hand, usually contain varying numbers

of conceptually identical values and use numbers (starting from 0) as the

names of their properties.

There are some named properties in arrays, such as length and a number

of methods. Methods are functions that live in properties and (usually) act

on the value they are a property of.

Objects can also serve as maps, associating values with names. The in

operator can be used to find out whether an object contains a property with

a given name. The same keyword can also be used in a for loop (for (var

Exercises

The Sum of a Range

The introduction of this book alluded to the following as a nice way to compute

the sum of a range of numbers:

console.log(sum(range(1, 10)));

Write a range function that takes two arguments, start and end, and

returns an array containing all the numbers from start up to (and including)

end.

Next, write a sum function that takes an array of numbers and returns the

sum of these numbers. Run the previous program and see whether it does

indeed return 55.

As a bonus assignment, modify your range function to take an optional

third argument that indicates the "step" value used to build up the array. If

no step is given, the array elements go up by increments of one, corresponding

to the old behavior. The function call range(1, 10, 2) should return

[1, 3, 5, 7, 9]. Make sure it also works with negative step values so that

range(5, 2, -1) produces [5, 4, 3, 2].

Reversing an Array

Arrays have a method reverse, which changes the array by inverting the

order in which its elements appear. For this exercise, write two functions,

reverseArray and reverseArrayInPlace. The first, reverseArray, takes an array

as an argument and produces a new array that has the same elements in

the inverse order. The second, reverseArrayInPlace, does what the reverse

method does: it modifies the array given as argument in order to reverse

its elements. Neither may use the standard reverse method.

Thinking back to the notes about side effects and pure functions in the

previous chapter, which variant do you expect to be useful in more situations?

Which one is more efficient?

A List

Objects, as generic blobs of values, can be used to build all sorts of data

structures. A common data structure is the list (not to be confused with the

array). A list is a nested set of objects, with the first object holding a reference

to the second, the second to the third, and so on.

var list = {

value: 1,

rest: {

value: 2,

78 Chapter 4

rest: {

value: 3,

rest: null

}

}

};

The resulting objects form a chain, like this:

value: 1

rest:

value: 2

rest:

value: 3

rest: null

A nice thing about lists is that they can share parts of their structure.

For example, if I create two new values {value: 0, rest: list} and {value:

-1, rest: list} (with list referring to the variable defined earlier), they are

both independent lists, but they share the structure that makes up their last

three elements. In addition, the original list is also still a valid three-element

list.

Write a function arrayToList that builds up a data structure like the

previous one when given [1, 2, 3] as an argument, and write a listToArray

function that produces an array from a list. Also write the helper functions

prepend, which takes an element and a list and creates a new list that adds

the element to the front of the input list, and nth, which takes a list and a

number and returns the element at the given position in the list, or undefined

when there is no such element.

If you haven't already, also write a recursive version of nth.

Deep Comparison

The == operator compares objects by identity. But sometimes, you would

prefer to compare the values of their actual properties.

Write a function, deepEqual, that takes two values and returns true only if

they are the same value or are objects with the same properties whose values

are also equal when compared with a recursive call to deepEqual.

To find out whether to compare two things by identity (use the ===

operator for that) or by looking at their properties, you can use the typeof

operator. If it produces "object" for both values, you should do a deep comparison.

But you have to take one silly exception into account: by a historical

accident, typeof null also produces "object".

Data Structures: Objects

"There are two ways of constructing a software

design: One way is to make it so simple that

there are obviously no deficiencies, and the

other way is to make it so complicated that

there are no obvious deficiencies"

— C.A.R. Hoare,

1980 ACM Turing Aware

   

'JavaScript' 카테고리의 다른 글

8장 버그와 에러  (0) 2016.11.13
9장 정규 표현식  (0) 2016.11.13
5장 Higher - Order Functions  (0) 2016.11.13
Chapter 1 - VALUES, TYPES, AND OPERATERS  (0) 2016.11.13