프로토타입과 배열 그리고 연산자

프로토타입

자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있다. 이를 통해 자바스크립트에서는 상속 개념을 구현할 수 있다. 이를 프로토타입 객체라고 한다.

var foo = {
  name: 'Jang',
  age: 27
};

console.log(foo.toString());
console.dir(foo);

코드를 한 번 살펴보자. 사실상 1번 콘솔로그에서 toString이라는 메서드가 없어 오류가 발생해야 하지만 정상적으로 작동한다.
즉, foo 객체의 부모 역할을 하는 프로토타입에 toString() 메서드가 이미 정의되어 있기 때문에 호출이 가능한 것이다.

출력결과

[object Object]
{ name: ‘Jang’, age: 27 }

즉 모든 객체는 자신의 프로토타입을 가리키는 [[Prototype]]이라는 숨겨진 프로퍼티를 가진다. (크롬 브라우저의 _proto_)
여기서 foo 객체는 자신의 부모 객체를 _proto_라는 내부 프로퍼티로 연결하고 있다.
자세한 내용은 프로토타입 체이닝에서 더 다루겠지만, 결론적으로 객체 리터럴로 생성한 객체의 경우 Object.prototype 객체가 프로토타입 객체이다.

배열

  • 배열 리터럴
    배열 리터럴은 ‘[]’를 사용해서 배열을 만든다.

    var colorArr = [‘orange’, ‘red’, ‘yellow’, ‘green’];
    console.log(colorArr[0]);
    console.log(colorArr[1]);

출력결과

orange
red

배열은 인덱스 값으로 접근할 수 있다. 배열 내 인덱스는 0부터 시작한다. 즉 첫번째 값의 인덱스는 0인 것이다.

  • 배열 요소 생성
    배열도 다른 객체와 마찬가지로 동적으로 배열 원소를 동적으로 추가할 수 있다.

    var empty = [];
    console.log(empty);

    empty[0] = 100;
    empty[3] = ‘four’;
    console.log(empty);
    console.log(empty.length);

출력 결과

[]
[ 100, undefined x 2, four ]
4

자바스크립트의 배열은 인덱스 순서와 상관없이 할당이 가능하다. 값이 없다면 undefined가 뜬다.
또한 중요한 점은 자바스크립트가 배열의 크기를 배열 인덱스 중 가장 큰 값을 기준으로 정한다.는 것이다.
또한 length 프로퍼티를 이용하여 배열의 길이를 구할 수 있다. 배열의 길이 값은 가장 큰 인덱스에 +1을 한 값이다.(인덱스의 시작이 0 이기 때문이다.)

  • length
    길이값은 위에서 설명했지만, 중요한 것은 길이값을 명시적으로 변경할 수 있고 그 길이를 초과하는 값은 삭제된다는 점이다.
    위 예제에서 empty의 length값은 4이지만 length값을 2로 설정하면, 100과 undefined를 제외한 뒤의 값은 삭제된다.
  • 배열과 객체
    배열과 객체는 모두 객체이지만 몇 가지 차이점이 있다. 우선 length 프로퍼티는 배열에만 존재한다. 두 번째로는 프로토타입의 차이이다.
    일반 객체는 push와 같은 표준 배열 메서드를 사용할 수 없는데 둘의 프로토타입 체이닝에 의한 부모 프로토타입 객체가 서로 다르기 때문이다.

객체 - _proto_ - Object.prototype
배열 - _proto_ - Array.prototype - _proto_ - Object.prototype

배열의 프로퍼티 열거

객체는 for in 문으로 객체를 열거할 수 있는데 배열은 for in문을 사용하면 불필요한 프로퍼티가 출력될 수 있으므로 for문을 사용하는 것이 좋다.

var arr = ['zero', 'one', 'two'];
console.log(arr.length);
arr[3] = 'red';
console.log(arr.length);

for (var i = 0; i < arr.length; i++) {
  console.log(i, arr[i]);
}

출력 결과

3
4
for문 결과값
0 ‘zero’
1 ‘one’
2 ‘two’
3 ‘red’

배열 요소 삭제

배열도 객체이므로 delete 연산자를 사용할 수 있지만, 이는 해당 요소를 undefined처리할 뿐이다. 그래서 배열에서는 splice()배열 메서드를 사용한다.

splice() 배열 메서드

splice(start, deleteCount, item…)

  • start : 배열에서 시작 위치, deleteCount : 삭제할 요소의 수 item : 삭제할 위치에 추가할 요소

    var arr = ['zero', 'one', 'two', 'three'];
    
    arr.splice(2,1); // 1
    console.log(arr);
    console.log(arr.length);
    

즉 1의 의미는 arr배열의 2번째부터 1개 요소를 삭제하겠다는 의미이다. 즉 arr 요소에서 ‘two’가 삭제되는 것이다.

출력 결과

[ ‘zero’, ‘one’, ‘three’ ]
3

Array() 생성자 함수

배열은 배열 리터럴로 생성하지만 배열 리터럴도 결국 Array()생성자 함수로 배열을 생성하는 것을 단수화한 것이다.
생성자 함수로 배열을 생성할 때에는 new 연산자를 사용하여야 한다.

var foo = new Array(3);
console.log(foo);
console.log(foo.length);

var bar = new Array(1,2,3);
console.log(bar);
console.log(bar.length);

호출할 때 인자가 1개이면 호출된 인자를 lenth로 갖는 빈 배열을 생성하고 그 외에는 호출된 인자를 요소로 같는다.

출력 결과

[ undefined x 3]
3
[1,2,3]
3

유사 배열 객체

length 프로퍼티는 배열의 동작에 있어서 정말 중요하다. 그런데 일반 객체에서도 length를 사용할 수 있는 경우가 있으니 이를 유사 배열객체라고 한다.

var arr = ['bar'];
var obj = { name: 'Jang', length : 1};

arr.push('baz');
console.log(arr);

Array.prototype.push.apply(obj, ['baz']);
console.log(obj);

원래의 경우라면 변수 obj에는 push()메서드를 사용할 수 없으나, apply() 메서드를 사용하면 객체라도 표준 배열 메서드를 사용할 수 있다.
후에 더 자세히 살펴볼 것이다. (call, apply 메서드)

출력 결과

[ ‘bar’, ‘baz’ ]
{ ‘1’: ‘baz’, name: ‘Jang’, length: 2 }

기본 타입과 표준 메서드

기본 타입의 경우 어떻게 표준 메서드를 호출하는가? 자바스크립트에서는 기본값을 객체로 변화한 다음 각 타입의 표준 메서드를 불러온다.

연산자

    • 연산자

+연산자는 더하기 연산과 문자열 연결 연산을 수행한다. 두 연산자가 모두 숫자인 경우에는 더하기 연산을 실시한다.

  • typeof 연산자

피연산자의 타입을 문자열 형태로 리턴하는 연산자이다. 유의할 점은 null의 경우 object로 표시된다는 점(자바스크립트 개발단 오류)
함수는 function이라는 점에 유의하여야 한다.

  • 동등연산자와 일치연산자.

동등연사자의 경우(==) 피연사자의 타입이 다를 경우 이를 변경하여 비교하고 일치연산자의 경우(===) 타입을 변경하지 않는다.

console.log(1 == '1') // true
console.log(1 === '1') // false
  • !! 연산자

!!연산자는 피연산자를 불리언값으로 변환한다. 값이 0이나 없다면 false, 그 외의 빈 객체, 배열, 문자열 등은 true로 표시된다.

다음 시간에는 함수와 프로토타입 체이닝에 대해서 알아보겠습니다.