[[]]
로 감싼 이름들이 모두 내부 슬롯과 내부 메서드이다.[[Prototype]]
이라는 내부 슬롯을 가진다.const obj = {};
obj.__proto__ // 이렇게 간접적으로만 참조 가능.
위의 코드처럼 obj.[[Prototype]]
이렇게는 참조할 수 없고 __proto__
로 간접적으로 참조할 수 있다.
[[Value]]
프로퍼티 값[[Writable]]
프로퍼티 수정 여부[[Enumerable]]
열거 여부[[Configurable]]
재정의 여부true
이다.[[Get]]
프로퍼티 값을 읽어올 때 호출되는 접근자 함수(getter)[[Set]]
프로퍼티 값을 저장할 때 호출되는 접근자 함수(setter)[[Enumerable]]
열거 여부[[Configurable]]
재정의 여부const obj={};
Object.definedProperties(obj, {
name: {
value: 'afk',
writable: 'true',
enumerable: 'true',
configurable: 'true'
}
}
구분 | 메소드 | 추가 | 삭제 | 읽기 | 쓰기 | 재정의 |
---|---|---|---|---|---|---|
객체 확장 금지 | Object.preventExtensions | X | O | O | O | O |
객체 밀봉 | Object.seal | X | X | O | O | X |
객체 동결 | Object.freeze | X | X | O | X | X |
new
연산자와 함께 인스턴스를 생성하는 함수를 말한다.=> 붕어빵 틀과 같다고 생각하면 될 것같다. 붕어빵 틀이라는 생성자 함수가 있다하면 const 붕어빵1 = new 붕어빵틀()
하면 붕어빵 틀에 찍혀 만들어진 붕어빵1 이라는 인스턴스가 생긴다.
const obj = new Circle();
위의 코드는 new 연산자를 사용해 obj 인스턴스를 생성했다.
먼저 암묵적으로 빈 객체가 생성된다.
그리고 이 빈 객체(인스턴스) 는 암묵적으로 this에 바인딩 된다.
=> 생성자 함수 내부의 this가 생성자 함수가 생성할 인스턴스를 가리키는 이유이다.
이 작업은 런타임 이전에 이루어진다.
function Circle(name, str){
this.name = name;
this.func = function(){
return this.name + str;
}
}
위는 Circle이라는 생성자 함수이며 예를 들어 const obj = Circle("kim", "afk");
이렇게 인스턴스를 생성했다하면 인수로 전달받은 초기값은 인스턴스 프로퍼티에 할당하여 초기화하거나 고정값을 할당한다.
생성자 함수 내부의 모든 처리가 끝나면 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
위에서 언급한 obj 인스턴스는 Circle {name: 'kim', func: f}
라는 프로퍼티 객체를 갖게 된다.
만약
function Circle(name, str){
this.name = name;
this.func = function(){
return this.name + str;
}
return {};
}
const obj = new Circle(); // {}
명시적으로 객체 타입을 반환하면 마지막 return 문을 따른다. 따라서 obj는 빈 객체가 된다.
그러나 원시타입을 명시적으로 반환하면 정상적으로 인스턴스를 생성한다.
[[Call]]
이 호출되고 new 연산자와 함께 생성자 함수로써 호출되면 내부메서드 [[Constructor]]
가 호출 된다.[[Call]]
을 갖는 함수 객체를 callbale 이라고 부른다.[[Constructor]]
을 갖는 함수 객체를 constructor 이라고 부른다.[[Constructor]]
을 갖지 않는 함수 객체를 non-constructor 이라고 부른다.=> 예를 들어 arrow function 과 객체 메소드 축약형은 constructor 내부 메서드가 존재하지 않는다. 따라서 생성자 함수로 사용할 수 없으며 non-constructor라고 부른다.