
섀도우 복싱 ㅋㅋㄹㅃㅃ
하위 객체에서 상위 객체 프로토타입 get
const Person = (function () {
//생성자 함수
function Person(name) {
this.name = name;
}
// 프로토타입 메서드
Person.prototype.sayHello = function () {
console.log(`Hello, Im ${this.name}`);
}
// 생성자 함수를 반환
return Person;
}())
// 인스턴스 생성
const me = new Person('Leona');
// 인스턴스 메서드
me.sayHello = function () {
console.log(`Hi, My name is ${this.name}`);
}
// 인스턴스 메서드 호출
me.sayHello(); // ???
하위 객체에서 상위 객체 프로토타입 set
// me 인스턴스에서 메서드 삭제
delete me.sayHello;
// me 인스턴스에는 sayHello 메서드가 없다.
me.sayHello(); // ???
delete Person.prototype.sayHello;
me.sayHello(); // TypeError: me.sayHello is not a functionconst Person = (function () {
function Person(name) {
this.name = name;
}
// 생성자 함수의 프로토타입 교체
Person.prototype = {
sayHello() {
console.log(`Hello world! My name is ${this.name}`);
}
}
return Person;
}());
const me = new Person('Leona');


const Person = (function () {
function Person(name) {
this.name = name;
}
// 생성자 함수의 프로토타입 교체
Person.prototype = {
constructor: Person,
sayHello() {
console.log(`Hello world! My name is ${this.name}`);
}
}
return Person;
}());

인스턴스의 _ proto _ 접근자 프로퍼티(or Object.setPrototypeOf 메서드)를 통해 프로토타입을 교체할 수 있다.
function Person(name) {
this.name = name;
}
const me = new Person('Leona');
// 프로토타입으로 교체할 객체
const parent = {
sayHello() {
console.log(`Hello world! My name is ${this.name}`);
}
}
// === me.__proto__ = parent;
Object.setPrototypeOf(me, parent);
me.sayHello();

생성자 함수의 prototype에 바인딩된 객체가 프로토타입 체인에 존재하면 true, 아니면 false를 리턴한다.
생성자 함수의 prototype에 바인딩된 객체가 프로토타입 체인에 존재하는지 확인한다.
function Person(name) {
this.name = name;
}
const me = new Person('Leona');
console.log(me instanceof Person); // true
console.log(me instanceof Object); // true
const me = new Person('Leona');
const parent = {};
Object.setPrototypeOf(me, parent);
// Object.prototype에 바인딩 했기 때문에 Person 객체와 체인이 끊긴 상태
console.log(me instanceof Person); // false
console.log(me instanceof Object); // true
Person.prototype = parent;
// Person 생성자 함수의 prototype에 바인딩 했기 때문에 체인이 걸렸다.
console.log(me instanceof Person); // true
console.log(me instanceof Object); // true
프로토타입을 명시적으로 지정해서 새로운 객체를 생성한다.
첫번째 매개변수인 객체의 프로토타입 체인에 속하는 객체를 생성한다.(상속을 직접 구현)
new 연산자 없이, 프로토타입을 지정하면서 생성하며, 객체 리터럴도 상속받을 수 있다.
Object.prototype을 상속받기 때문에 해당 객체의 메서드를 호출할 수 있다.(hasOwnProperty 등)
// prototype: 생성할 객체의 프로토타입으로 지정할 객체
// propertiesObject: 생성할 객체의 프로퍼티를 갖는 객체
Object.create(prototype[, propertiesObject]);
// Object.prototype 상속받기
const obj = Object.create(
Object.prototype, {
x: {
value: 1,
writable: true,
enumerable: true,
configurable: true,
}
});
console.log(Object.getPrototypeOf(obj) === Object.getPrototype); // true
// 임의의 객체 상속받기
const proto = { y: 2 };
const obj2 = Object.create(proto);
console.log(Object.getPrototypeOf(obj2) === proto); // true
// 생성자 함수 상속받기
function Person(name) {
this.name = name;
}
const obj3 = Object.create(Person.prototype);
obj3.name = 'Leona';
console.log(obj3.name); // Leona
console.log(Object.getPrototypeOf(obj3) === Person.prototype); // true
ES6에서 객체 리터럴 내부 _ proto _ 접근자 프로퍼티로 직접 상속 구현
const proto = { x: 1};
const obj = {
y: 2,
__proto__: proto,
}
console.log(obj.x, obj.y); // 1, 2
console.log(Object.getPrototypeOf(obj) === proto); // true
생성자 함수로 인스턴스를 생성하지 않아도 참조 및 호출할 수 있는 프로퍼티, 메서드
생성자 함수가 생성한 인스턴스는 자신의 프로퍼티, 메서드에 접근할 수 있지만, 프로퍼티, 메서드가 인스턴스에 접근할 수 없다. => 프로토타입 체인에 속하지 않았기 때문
// 생성자 함수
function Person(name) {
this.name = name;
}
// 정적 프로퍼티
Person.staticProp = 'static prop';
// 정적 메서드
Person.staticMethod = function () {
console.log('static method');
}
const me = new Person('Leona');
Person.staticMethod(); // static method
me.staticMethod(); // TypeError: staticMethod is not a function
객체 내에 특정 프로퍼티가 있는지 확인하는 연산자
key in object
const person = {
name: 'Leona',
age: 30,
}
console.log('name' in person); // ???
console.log('address' in person); // false
console.log('age' in person); // ???
객체 프로퍼티 뿐 아니라 객체가 상속받는 모든 프로토타입의 프로퍼티를 확인한다.
객체가 속한 프로토타입 체인 상에 존재하는 모든 프로토타입을 검색하기 때문
// Object.prototype 메서드
console.log('toString' in person); // true
ES6에서는 Reflect.has 메서드를 쓸 수 있다.
Reflect.has(person, 'name'); // true
person.hasOwnProperty('name'); // true
person.hasOwnProperty('address'); //false
for (const key in person) {
console.log(key + ': ' + person[key]); // name: Leona, age: 30 ...
}const person = {
name: 'Leona',
age: 30,
}Object.keys(person); // ['name', 'age']Object.values(person); // ['Leona', '30']Object.entries(person); // [['name', 'Leona']], ['age', 30]]