인프런 강의 자바스크립트 중급 - 코딩앙마 를 듣고 정리한 내용입니다.
객체는 hasOwnProperty
메소드로 자신이 해당 프로퍼티를 가지고 있는지 확인할 수 있습니다.
const user = {
name : 'Mike'
}
user.hasOwnProperty('name') // true
user.hasOwnProperty('age') // false
hasOwnProperty
라는 메소드는 proto
라는 객체에 담겨 있고, 이를 프로토타입이라고 합니다. 객체에서 프로퍼티를 읽으려고 하는 데 없을 경우 프로토타입에서 해당 값을 찾게 됩니다.
아래와 같이 중복되는 프로퍼티를 가진 객체가 있을 때
const bmw = {
color: "red",
wheels: 4,
navigation: 1,
drive() {
console.log("drive..");
},
}
const benz = {
color: "black",
wheels: 4,
drive() {
console.log("drive..");
},
}
const audi = {
color: "blue",
wheels: 4,
drive() {
console.log("drive..");
}
}
중복되는 프로퍼티를 별도의 객체로 묶어주고, 그 객체를 프로토타입으로 넣어줄 수 있습니다. 이를 상속된다고 합니다.
// 중복되는 요소를 묶은 상위 개념의 객체를 만들고
const car = {
wheels: 4,
drive() {
console.log("drive..");
}
}
// 기존 객체들의 중복요소들을 지우고
const bmw = {
color: "red",
navigation: 1,
}
const benz = {
color: "black",
}
const audi = {
color: "blue",
}
// car 가 각 객체의 프로토타입이 되도록 작성
bmw.__proto__ = car;
benz.__proto__ = car;
audi.__proto__ = car;
// 각 객체는 car 의 상속을 받는 것
해당 객체에서 프로퍼티를 찾아보고 없으면, 상속받는 프로토타입에서 찾고, 없으면 그 상위 상속에서 찾습니다. 상속은 계속 이어질 수 있습니다. 이렇게 상속이 연결되는 것을 Prototype chain
이라고 합니다. for in
문을 사용하면 상속받는 값을 모두 보여주지만, 객체의 key
나 value
를 호출하면 상속받은 값이 나오지 않습니다.
아래와 같은 생성자 함수가 있을 때,
const Bmw = function (color) {
this.color = color;
this.wheels = 4;
this.drive = function() {
console.log("drive..");
};
};
const x5 = new Bmw("red");
const z4 = new Bmw("blue");
// 새로운 컬러를 넣어준 새로운 객체 만들기
매개변수로 넘겨준 컬러를 제외하고 중복되는 요소는 분리하고 프로토타입으로 상속할 수 있습니다.
// 중복되는 값 묶어주고
const car = {
wheels: 4,
drive() {
console.log("drive..");
},
};
// 중복되는 값 지워주고
const Bmw = function (color) {
this.color = color;
};
// 생성자 함수로 새로운 객체 만들어주고
const x5 = new Bmw("red");
const z4 = new Bmw("blue");
// 해당 객체에 car 의 값을 상속 해준다.
x5.__proto__ = car;
z4.__proto__ = car;
위 코드에서 두가지 요소는 결합할 수 있습니다.
// 기존 코드
const car = {
wheels: 4,
drive() {
console.log("drive..");
},
};
x5.__proto__ = car;
z4.__proto__ = car;
// 수정 코드
Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function() {
console.log("drive..");
};
이렇게 하면 생성자 함수를 만들 때 하나하나 상속해주지 않아도 됩니다. 생성자 함수가 새로운 객체를 만들 때, 그 객체는 생성자의 instance
라고 부릅니다. js
에서는 이를 확인하는 instanceof
연산자가 있습니다. 해당 객체가 그 생성자함수로 만들어진 것이 많으면 true
아니면 false
를 반환합니다.
z4 instanceof Bmw // ture
z4.constructor === Bmw; // true - 생성자 확인하기
위에서 작성한 코드를 약간 바꾸어 보면
// 기존 코드
Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function() {
console.log("drive..");
};
// 수정 코드
Bmw.prototype = {
wheels = 4,
drive() {
console.log("drive..");
},
}
// 이렇게 바꾸면 생성자 함수가 false 가 나옵니다.
z4.constructor === Bmw; // false
// 이런 현상을 방지하기 위해서 기존처럼 하나씩 프로퍼티를 추가하는 게 좋습니다.
// 굳이 수정한다면 아래처럼 수도로 명시해주어야 합니다.
Bmw.prototype = {
constructor: Bmw, // 생성자 명시
wheels = 4,
drive() {
console.log("drive..");
},
}
// 생성자는 명확히 보장되지 않습니다. 개발자가 변경할 수 있습니다.
다른 예제를 살펴보면,
const Bmw = function(color) {
this.color = color;
};
const x5 = new Bmw("red");
// 이렇게 작성하면
x5.color // red
// 그런데 아래처럼 새로운 값을 넣을 수 있습니다. 값이 변경될 수 있습니다.
x5.color = "black"
// 이를 방지하기 위해 클로저를 활용한다면,
const Bmw = function(color) {
const c = color;
this.getColor = function() {
console.log(c);
}
};
const x5 = new Bmw("red");
// 초기 세팅한 값만 얻고, 이후 수정이 안됩니다.
// getColor 는 생성될 당시의 콘텍스트를 기억합니다.