객체란..?
{}안에 0개의 프로퍼티로 구성된 집합이다.
프로퍼티는 키와 값으로 구성된다.
자바스크립트에는 원시 타입의 값과 객체 타입으로 나뉜다.
원시 타입의 값은 변경 불가능한 값(immutable value)이지만, 객체 타입의 값 즉, 객체는 변경 가능한 값(mutable value)이다. 자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있다.
키는 빈 문자열, 모든 문자열 그리고 심벌 값을 사용할 수 있다.
키(key) : 모든 문자열(빈 문자열), 심벌 값
값(value) : 자바스크립트에서 사용할 수 있는 모든 값
var person = {
name : 'Kim',
age : 30
};
위에 코드로 예시를 들자면 {}안에 값들이 프로퍼티
key : name, age
value : 'Kim', 30
객체 중괄호 끝에는 세미 콜론을 붙입니다. 이유는 객체 리터럴의 중괄호는 코드 블록을 의미하지 않습니다. 객체 리터럴은 값으로 평가되는 표현식입니다. 따라서 객체 리터럴의 중괄호 뒤에는 세미콜론(;)을 붙입니다.
메서드
객체 안에 있는 함수를 일반 함수와 구분하기 위해 메서드라고 부릅니다.
var person = {
name : 'Lee',
sayHello : function () {
console.log(`Hello My name is ${this.name}.`);
}
};
객체 안에 sayHello()라는 메서드가 있습니다.
프로퍼티
프로퍼티를 나열할 때는 쉼표(,)로 구분합니다. 일반적으론 마지막 프로퍼티 뒤에는 쉼표를 사용하지 않지만, 사용 해도 괜찮습니다.
var person = {
// 프로퍼티 키는 name, 프로퍼티 값은 : 'Kim'
name : 'Kim',
// 프로퍼티 키는 age, 프로퍼티 값은 : 30
age : 30
}
프로퍼티 키는 프로퍼티 값에 접근할 수 있는 이름으로서 식별자 역할을 합니다.(식별자와 동일한건 아니지만, 역할을 한다 라고 생각하시면 될 것 같습니다.)
그렇다고 해서 식별자 네이밍 규칙을 반드시 따라야 하는 것은 아닙니다. 단, 식별자 네이밍 규칙을 준수하는 프로퍼티 키와 그렇지 않은 프로퍼티 키는 차이가 있습니다.
식별자 네이밍 규칙을 따른 키는 따옴표를 생략할 수 있습니다. 즉, 식별자 네이밍 규칙을 따르지 않은 식별자 네임은 반드시 따옴표를 사용해야 합니다.
var person = {
firstName : 'Lee', // 식별자 네이밍 규칙을 준수한 프로퍼티 키
'last-name' : 'Jieun' // 식별자 네이밍 규칙을 준수하지 않은 프로퍼티 키
};
var person = {
firstName : 'Lee',
last-name : 'Jieun' // SyntaxError : Unexpected token -
// 식별자 네이밍 규칙을 따르지 않고 따옴표도 생략한다면 자바스크립트 엔진은
// - 연산자가 있는 표현식으로 해석한다.
};
프로퍼티 접근
프로퍼티 접근에는 두 가지 방법이 있습니다.
1. 마침표 표기법
2. 대괄호 표기법
프로퍼티 키가 식별자 네이밍을 준수하는 이름이면 두 가지 방법 모두 사용할 수 있습니다. 하지만 식별자 네이밍 규칙을 지키지 않은 식별자 이름은 반드시 대괄호 표기법을 사용해야 하며 반드시 따옴표를 사용해야 합니다.
대괄호 표기법을 사용할 때 따옴표를 사용하지 않으면 자바스크립트 엔진은 식별자로 인식을 합니다.
객체로 평가되는 표현식을 좌측에 기술하고, 마침표 프로퍼티 접근 연산자의 우측 또는 대괄호 표기법 내부에는 프로퍼티 키를 지정합니다.
var person = {
name : 'Kim'
};
// 점 표기법
console.log(person.name); // Kim
// 대괄호 표기법
console.log(person['name']); // Kim
console.log(person[name]); // ReferenceError : name is not defined
console.log(person.age); // Undefined
위에서 ReferenceError에러가 뜨는 이유는 따옴표를 사용하지 않으면 자바스크립트 엔진은 식별자로 인식하기 때문에 선언된 name을 찾았지만 찾지 못했기 때문입니다.
객체제 존재하지 않는 프로퍼티에 접근하면 undefined가 반환되고, ReferenceError가 발생하지 않는다는 것을 주의 하시기 바랍니다!!
식별자 네이밍을 준수 하지 않은 식별자를 사용할 경우 꼭 대괄호 표기법을 사용하고 반드시 따옴표를 사용해야 합니다.
식별자 네이밍 규칙을 지키지 않은 키 값은 두 환경에서 다르게 나타납니다.
var person = {
firstName : 'Lee', // 식별자 네이밍 규칙을 준수한 프로퍼티 키
'last-name' : 'Jieun' // 식별자 네이밍 규칙을 준수하지 않은 프로퍼티 키
};
person.'last-name'; // SyntaxError
person.last-name; // 브라우저 환경 : NaN
// Node.js 환경 : ReferenceError
person[last-name]; // ReferenceError
person['last-name']; // Jieun
위에 코드에서 person.last-name은 브라우저 환경과 Node.js 환경에서 서로 다르게 나타냅니다. 우선 자바스크립트 엔진은 person.last로 평가를 합니다. 하지만 last로 선언된 프로퍼티 키가 없으므로 undefined를 반환합니다.!
브라우저 환경
브라우저는 person.lsat-name을 person.last는 없으므로 undefined를 반환하고 - 연산자로 인식을 하기 때문에 undefined - name을 합니다. 하지만 name은 여기서 식별자로 인식됩니다. 브라우저 환경에서는 name이 전역 변수(전역 객체 window의 프로퍼티)가 암묵적으로 존재합니다. 그러므로 name은 창(window)의 이름을 가르키며, 기본값은 문자열입니다. 따라서 undefined - ''과 같으므로 NaN이 출력됩니다.
Node.js
Node.js환경에서는 name을 찾지만 선언된 프로퍼티 키가 없으므로 ReferenceError : name is not defined가 나오는 것입니다.
프로퍼티 값 갱신
자바스크립트 객체는 프로퍼티 값을 갱신할 수 있습니다.
var person = {
name : 'Kim'
};
// person객체에 name 프로퍼티가 존재하므로 name 프로퍼티의 값이 갱신됩니다.
person.name = 'Son';
console.log(person); // {name: "Son"}
프로퍼티 동적 생성
존재 하지 않은 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.
var person = {
name : 'Kim'
};
// person객체엔 age 프로퍼티가 존재하지 않는다.
// person객체에 age 프로퍼티가 동적으로 생성되고 값이 할당된다.
person.age = 25;
console.log(person); // {name: "Kim", age: 25}
프로퍼티 삭제
delete 연산자로 객체의 프로퍼티를 삭제할 수 있고, 만약 존재하지 않는 프로퍼티 키에 접근하면 아무런 에러 없이 무시된다.
var person = {
name : 'Kim',
age : 25
};
delete person.age; // 존재 하므로 프로퍼티 삭제가 된다.
delete person.address; // 존재 하지 않으므로 에러 없이 무시된다.
console.log(person); // {name: "Kim"}
프로퍼티 축약 표현
프로퍼티 값으로 변수를 사용하는 경우 변수 이름과 프로퍼티 키가 동일한 이름일 때 프로퍼티 키를 생략할 수 있다. 이때 프로퍼티 키는 변수이름으로 자동 생성된다.
let x = 1;
let y = 2;
const obj = {
x: x,
y: y
};
console.log(obj); // {x: 1, y: 2}
// 축약 표현
const obj = { x, y };
console.log(obj); // {x: 1, y: 2}
// 메서드도 축약 표현이 가능하다.
// 일반
var obj = {
name: 'Kim',
sayHi: function() {
console.log('Hi! ' + this.name);
}
};
obj.sayHi(); /// Hi! Kim
// 축약 표현
var obj = {
name: 'Kim',
sayHi() {
console.log('Hi! ' + this.name);
}
};
obj.sayHi(); /// Hi! Kim
메서드 축약 표현으로 정의한 메서드는 프로퍼티에 할당한 함수와 다르게 동작하는데,, 이건 나중에 다른 내용과 함께 정리 하겠습니다.
공부를 하면서 느낀게 정말 식별자 네이밍을 잘 지키고 네임을 지어야 겠다고 다시 한번 느꼈습니다. 좋은 개발자가 되기 위해 동료,다른 개발자가 보더라도 어떤 코드인지 알 수 있게 네이밍을 신중하게 생각해서 지어야 할 것 같습니다. 아직 중요한 내용이 많이 남았지만, 차차 정리해서 올려보도록 하겠습니다.!
현재 '모던 자바스크립트 Deep Dive'를 통해 자바스크립트를 학습하고 있습니다. 본 포스트는 해당 내용에 대한 정리를 목적으로 합니다.