상속, 프로토타입(Prototype)

라용·2022년 8월 10일
0

인프런 강의 자바스크립트 중급 - 코딩앙마 를 듣고 정리한 내용입니다.

객체는 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 문을 사용하면 상속받는 값을 모두 보여주지만, 객체의 keyvalue 를 호출하면 상속받은 값이 나오지 않습니다.
아래와 같은 생성자 함수가 있을 때,

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 는 생성될 당시의 콘텍스트를 기억합니다.
profile
Today I Learned

0개의 댓글