2022-09-27 TIL

김재훈·2022년 9월 28일
0

TIL

목록 보기
5/7

추가로 배워야 하거나 정리할 내용들

2022-09-20

  • 블록 레벨 스코프와 함수 레벨 스코프
  • 모던 자바스크립트 Deep Dive의 프로토타입 파트까지 학습 후 프로토타입 기반 프로그래밍에 대한 설명글 작성

2022-09-27

  • DOM 개체 readyState 프로퍼티의 역할
  • XMLHTTPRequest의 역할
  • popstate 이벤트 발생 시점
  • addEventListener()에서 매개변수 false의 역할

'모던 자바스크립트 Deep Dive' 학습

10장 객체 리터럴

10.3 프로퍼티(p. 127~)

식별자 네이밍 규칙을 따르지 않는 이름도 프로퍼티 키로 사용할 수 있지만 따옴표를 함께 사용해야 합니다.

var person = {
    firstName: 'Jae-hun',        // 식별자 네이밍 규칙을 따른 프로퍼티 키
    'last-name': 'Kim'           // 식별자 네이밍 규칙을 따르지 않은 프로퍼티 키
    last-name: 'Kim'             // SyntaxError: Unexpected token -
};

console.log(person);             // { firstName: 'Jae-hun', 'last-name': 'Kim' }

문자열 또는 문자열로 평가할 수 있는 표현식을 이용해 프로퍼티 키를 동적으로 생성할 수 있습니다. ```javascript var obj = {}; var key = 'hello';

// ES5: 프로퍼티 키 동적 생성
obj[key] = 'world';
// ES6: 계산된 프로퍼티 이름
var obj2 = { [key]: 'world' };

console.log(obj); // { hello: 'world' }
console.log(obj2); // { hello: 'world' }


<br>
빈 문자열도 프로퍼티 키로 사용할 수는 있으나 의미를 갖지 못 하므로 권장하지 않으며, 프로퍼티 키로 숫자 리터럴을 사용하는 경우 따옴표는 붙지 않지만 내부적으로는 문자열로 변환됩니다. var, function과 같은 예약어를 프로퍼티 키로 사용할 수도 있지만 예상치 못 한 에러가 발생할 여지가 있으므로 사용하지 않습니다.
만약 프로퍼티 키 이름에 중복된 이름을 사용한다면 나중에 선언된 프로퍼티의 값으로 덮어 씁니다.
<hr><br>

### 10.5 프로퍼티 접근(p.130~)
프로퍼티에 접근하는 방법은 다음과 같이 두 가지가 있습니다.
- dot notation(마침표 표기법): 마침표 프로퍼티 접근 연산자(`.`)를 사용
- bracket notation(대괄호 표기법): 대괄호 프로퍼티 접근 연산자(`[ ... ]`)를 사용

대괄호 표기법의 경우 대괄호 프로퍼티 접근 연산자 내부에 프로퍼티 키 이름은 반드시 따옴표로 감싼 문자열이어야 합니다.
```javascript
var person = {
    name: 'Jaehun'
};

// dot notation
console.log(person.name); // Jaehun

// bracket notation
console.log(person['name']); // Jaehun
console.log(person[name]); // ReferenceError: name is not defined

객체에 존재하지 않는 프로퍼티에 접근할 경우 ReferenceError가 아닌 undefined를 반환합니다.

var person = {
    name: 'Jaehun'
};

console.log(person.age); // undefined

프로퍼티 키가 식별자 네이밍 규칙을 준수하지 않는 경우 반드시 대괄호 프로퍼티 접근 연산자를 사용해야 하며, 대괄호 표기법에서도 프로퍼티 키가 숫자인 경우에는 따옴표를 생략할 수 있습니다.

var person = {
    'last-name': 'Jaehun',
    1: 10
};

person.'last-name';     // -> SyntaxError: Unexpected string
person.last-name;       // -> 브라우저 환경: NaN
                        // -> Node.js 환경: ReferenceError: name is not defined
person[last-name];      // -> ReferenceError: last is not defined
person['last-name'];    // Jaehun

// 프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략
person.1;       // -> SyntaxError: Unexpected number
person.'1';     // -> SyntaxError: Unexpected string
person[1];      // -> 10 : person[1] -> person['1']
person['1'];    // -> 10

위 예제에서 person.last-name에 대한 오류가 환경 별로 다른 이유는 다음과 같습니다.

  1. 자바스크립트 엔진이 해당 구문을 실행할 때 먼저 person.last로 평가됩니다.
  2. person 객체에는 last 프로퍼티가 없기 때문에 undefined로 평가되며, 따라서 person.last-nameperson.undefined-name과 같은 의미입니다.
  3. 자바스크립트 엔진은 name을 기본적으로 프로퍼티 키가 아닌 식별자로 인식함
  4. 이에 환경적 특성에 따라 다음과 같은 차이가 발생합니다.
    - Node.js 환경: 어디에서도 name이라는 식별자를 찾을 수 없기 때문에 RefrenceError: name is not defined 에러 발생
    - 브라우저 환경: name이라는 전역 변수가 암묵적으로 존재하며(전역 객체 window의 프로퍼티), 기본값은 빈 문자열임, 따라서 person.last-nameundefined - ''로 평가되어 NaN이 됨

10.7 프로퍼티 동적 생성(p.133~)

이미 존재하는 프로퍼티에 값을 할당하면 갱신되며, 존재하지 않는 프로퍼티에 값을 할당하면 동적으로 생성되어 추가됩니다.

var person = {
    name: 'Lee'
};

// 프로퍼티 값 갱신
person.name = 'Kim';

// 프로퍼티 동적 생성
person.age = 24;

console.log(person); // { name: 'Kim', age: 24 }

10.8 프로퍼티 삭제

프로퍼티를 삭제하고 싶을 때는 delete 연산자를 사용합니다. 사용 시 유의할 점으로 존재하지 않는 프로퍼티 삭제가 아무런 에러 없이 무시됩니다.

var person = {
    name: 'Kim'
};

person.age = 24;
delete person.age;

// 존재하지 않는 프로퍼티 삭제
delete person.address;

console.log(person); // { name: 'Kim' }

10.9 ES6에서 추가된 객체 리터럴의 확장 기능(p.134~)

객체 리터럴의 프로퍼티는 키와 값으로 구성되며, 프로퍼티 값은 변수에 할당된 값, 즉 식별자 표현식일 수 있습니다. ES6에서는 프로퍼티 값으로 사용할 변수 이름과 프로퍼티 키가 동일한 경우 프로퍼티 키를 생략할 수 있는데 이를 프로퍼티 축약 표현이라고 합니다.

var x = 1, y = 2;

var objES5 = {
    x: x,
    y: y
};

// 프로퍼티 축약 표현
var objES6 = { x, y };

console.log(objES5); // { x: 1, y: 2 }
console.log(objES6); // { x: 1, y: 2 }

위에서 설명했던 프로퍼티 키 동적 생성 시 문자열 또는 문자열로 타입 변환될 수 있는 값으로 평가되는 표현식을 프로퍼티 키 이름으로 사용할 수도 있으며, 이를 계산된 프로퍼티 이름이라고 합니다.

var prefix = 'prop';
var i = 0;

var obj = {};

// 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;

console.log(obj); // { 'prop-1': 1, 'prop-2': 2, 'prop-3': 3 }

ES6부터는 계산된 프로퍼티 이름을 객체 리터럴 내부에서도 사용 가능해졌으며, 사용 방법은 아래 예제와 같습니다.

const prefix = 'prop';
let i = 0;

// 객체 리터럴 내부에서 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성
const obj = {
    [`${prefix}-${++i}`]: i,
    [`${prefix}-${++i}`]: i,
    [`${prefix}-${++i}`]: i
};

console.log(obj); // { 'prop-1': 1, 'prop-2': 2, 'prop-3': 3 }

ES5에서는 메서드를 정의하려면 프로퍼티 값으로 함수를 할당했으나, ES6부터는 function 키워드를 생략하고 정의가 가능하며 이를 메서드 축약 표현이라고 합니다.
여기서 메서드는 메서드 축약 표현으로 정의한 함수만을 메서드라고 하며, 메서드는 인스턴스를 생성할 수 없는 non-constructor로 생성자 함수로서 호출할 수 없습니다.

var objES5 = {
    name: 'Kim',
    sayHi: function() {
        console.log('Hi! ' + this.name);
    }
};

var objES6 = {
    name: 'Kim',
    // 메서드 축약 표현 사용
    sayHi() {
        console.log('Hi! ' + this.name);
    }
}

objES5.sayHi(); // Hi! Kim
objES6.sayHi(); // Hi! Kim

ES6 명세에서 이렇게 구분되었으며 자세한 내용은 책의 26.2절 메서드에서 다시 다룹니다.

profile
개발하면서 새롭게 배운 내용, 시행착오한 내용들을 잊지 않기 위해 기록합니다.

0개의 댓글