객체
원시 타입의 값, 즉 원시 값은 변경 불가능한 값이지만 객체 타입의 값, 즉 객체는 변경 가능한 값이다. 자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있다. 자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다.
프로퍼티: 객체의 상태를 나타내는 값
메서드: 프로퍼티를 참조하고 조작할 수 있는 동작
객체 리터럴에 의한 객체 생성
//객체 생성 방법
1. 객체 리터럴
2. Object 생성자 함수
3. 생성자 함수
4. Object.create 메서드
5. 클래스(ES6)
//객체 리터럴 생성
var person ={
name: 'Lee',
sayHello: function(){
console.log(`Hello: My name is ${this.name}`);
}
}
console.log(typeof person); //object
console.log(person); // {name:'Lee', sayHello: f}
//빈 객체
var empty = {}; //빈 객체
console.log(typeof empty); //object
프로퍼티
//객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구성된다.
var person = {
//프로퍼티 키는 name, 프로퍼티 값은 'Lee'
name: 'Lee'
}
프로퍼티 키: 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
프로퍼티 값: 자바스크립트에서 사용할 수 있는 모든 값
식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용해야 한다.
var person = {
firstName: 'ye-na',
'last-name': 'Lee', //식별자 네이밍 규칙을 준수하지 않는 프로퍼티 키
middle-name : 'dori' //SyntaxError: Unexpected token -
}
var obj = {};
var key = 'name';
//ES5: 프로퍼티 키 동적 생성
obj[key] = 'yena';
//ES6: 계산된 프로퍼티 이름
console.log(obj); //{name: 'yena'}
//빈 문자열도 프로퍼티 키로 사용할 수 있다.
var foo = {
'':''
}
console.log(foo); // {'':''}
//프로퍼티 키로 숫자 리터럴을 사용하면 따옴표는 붙지 않지만 내부적으로는 문자열로 변환된다.
var foo = {
0:1,
1:2,
2:3
}
console.log(foo); //{0:1,1:2,2:3}
//프로퍼티 키를 중복 선언하면 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어쓴다.
var foo = {
name: 'yena',
name: 'yerin'
}
console.log(foo); //{name: "yerin"}
메서드
프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라 부른다. 즉, 메서드는 객체에 묶여 있는 함수를 의미한다.
프로퍼티 접근
//프로퍼티에 접근하는 방법
1. 마침표 프로퍼티 접근 연산자(.)를 사용하는 마침표 표기법
2. 대괄호 프로퍼티 접근 연산자([...])를 사용하는 대괄호 표기법
var person ={
name: 'yena'
}
//마침표 접근법
console.log(person.name);
//대괄호 표기법
console.log(person[name]);
//객체에 존재하지 않는 프로퍼티에 접근하면 undefined를 반환한다.
console.log(person.age); //undefined
var person = {
'last-name': 'kim',
1:10
}
person.'last-name'; //SyntaxError: Unexpected string
person.last-name; //Nan
person[last-name]: //ReferenceError: last is not defined
person['last-name']: //Kim
//프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있다.
person.1; //SyntaxError: Unexpected number
person.'1'; //SyntaxError: Unexpected string
person.[1]; //10
person['1']; //10
프로퍼티 값 갱신, 생성, 삭제
var person = {
name: 'yerin'
};
person.name = 'yena';
console.log(person); //{name:"yena"}
//프로퍼티 동적 생성
person.age = 25;
console.log(person); // {name:"yena", age:25}
//프로퍼티 삭제
delete person.age;
console.log(person); //{name:"yena"}
ES6에서 추가된 객체 리터럴의 확장
//프로퍼티 축약 표현
//ES5
var x=1, y=2;
var obj = {
x: x,
y: y
};
console.log(obj); //{x:1,y:2}
//ES6
const obj = {x,y};
console.log(obj); //{x:1,y:2}
//계산된 프로퍼티 이름
//ES5
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}
const obj ={
[`${prefix}-${++i}`]: i,
[`${prefix}-${++i}`]: i,
[`${prefix}-${++i}`]: i
};
console.log(obj); //{prop-1:1, prop-2:2, prop-3:3}
//메서드 축약 표현
//ES5
var obj ={
name: 'yena',
sayHi: function(){
console.log('HI: '+this.name);
}
};
obj.sayHi(); //Hi: yena
//ES6
var obj = {
name: 'yena',
sayHi(){
console.log('HI: '+this.name);
}
};
obj.sayHi(); //Hi: yena
Object 생성자 함수
//빈 객체의 생성
const person = new Object();
//프로퍼티 추가
person.name = 'lee';
person.sayHello = function(){
console.log('Hi! My name is '+this.name);
};
//반드시 Object 생성자 함수를 사용해 빈 객체를 생성해야 하는 것은 아니다.
객체를 생성하는 방법은 객체 리터럴을 사용하는 것이 더 간편하다.
Object 생성자 함수를 사용해 객체를 생성하는 방식은 특별한 이유가 없다면 그다지 유용해 보이지 않는다.
//객체 리터럴에 의한 객체 생성 방식의 문제점
객체 리터럴에 의한 객체 생성 방식은 직관적이고 간편하다.
하지만 객체 리털러에 의한 객체 생성 방식은 단 하나의 객체만 생성한다.
객체를 여러 개 생성해야 하는 경우 매번 같은 프로퍼티를 기술해야 하기 때문에 비효율적이다.
//생성자 함수에 의한 객체 생성 방식의 장점
생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성할 수 있다.
//생성자 함수
function Circle(radius){
this.radius = radius;
this.getDimeter = function(){
return 2 * this.radius;
}
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
//non-constructor 함수
1) 화살표 함수
const arrow = () => {};
new arrow(); //TypeError: arrow is not a constructor
2)ES6의 메서드 축약 표현
const obj ={
x(){}
};
new obj.x(); //TypeError:obj.x is not a constructor
new 연산자
new 연산자와 함께 함수를 호출하면 해당 함수는 생성자 함수로 동작한다. 함수 객체의 내부 메서드 [[Call]]이 호출되는 것이 아니라 [[Construct]]가 호출된다.
//생성자 함수
function Circle(radius){
this.radius = radius;
this.getDimeter = function(){
return 2 * this.radius;
};
}
//new 연산자 없이 생성자 훔수 호출하면 일반 함수로서 호출된다.
const circle = Circle(5);
console.log(circle); //undefined
//new.target ES6
new 연산자와 함께 생성자 함수로서 호출되면 함수 내부의 new.target은 함수 자신을 가리킨다.
new 연산자 없이 일반 함수로서 호출된 함수 내부의 new.target은 undefined다.
if(!new.target){
return new Circle(radius);
}
//스코프 세이프 생성자 패턴
if(!(this instanceof Circle)){
return new Circle(radius);
}
'Javascript > javascript Core' 카테고리의 다른 글
[Javascript 강의] 8강 스코프 (0) | 2021.09.25 |
---|---|
[Javascript 강의] 7강 함수 (0) | 2021.09.18 |
[Javascript 강의] 5강 제어문 (0) | 2021.09.14 |
[Javascript 강의] 4강 연산자 (0) | 2021.09.12 |
[Javascript 강의] 3강 데이터 타입 (0) | 2021.09.12 |