JS(자바스크립트) 이해하기 어려운 부분들을 복습삼아 글을 쓴다.
상속관점에서 유일한 생성자는 객체뿐이다.
은닉속성을 가지는데 바로 프토로타입! 프로토타입을 계속 찾아나서고 이를 프로토타입 체인이라한다.
이러한 점이 JS의 약점이라하지만 상송모델은 고전적?이다 할 수 있으며 더 강력한 방법이라할 수 있다.
프로토타입적 모델에서 고전적인 방식 구현은 꽤나 사소한 일이지만 그 반대는 훨씬 어려운일이기 때문.
프로토타입 체인을 이용한상속!
모든 함수는 prototype이라는 특수한 속성을 갖는다.
let f = function(){
this.a = 1
}
let o = new f();
f.prototype.a = 2;
f.prototype.b = 3;
f라는 함수 o라는 객체가 있다. 객체 o는 속성 a를 가지고 있다.
함수 f에 프로토타입 속성 값을 추가하였다.(b)
o.prototype 의 속성은 a와 b.
o.prototype.prototype = object.prototype
o.prototype.prototype.prototype = null (종단이다)
o.a = 1 (속성값) 단 프로토타입이 속성을 가지지만 이값은 쓰이지 않는다.(2값) "prototype shadowing"
o.b 는 속성을 가지지 않는다. o.prototype은 b라는 속성을 가지고있다.
그럼 o.c는 속성을 가지지도 않고 o.prototype에도 가지고 있지 않다. o.prototype.prototype.prototype = null 이다.
그렇기에 undefined를 반환한다.
JS에서 메소드라는 건 없다 객체의 속성으로 함수를 지정할 수 있고 속성값을 사용하듯 쓸 수 있다.
마치 자기가 가지고있는 것마냥 사용한다.
상속함수 실행될때 this라는 변수는 상속된 오브젝트를 가르킨다.
var o = {
a:2,
b: function(b){
return this.a+1;
}
};
var p = object.create(o);
p.a = 12;
o.b = this는 함수o의 a+1 를 리턴. 즉 this = 함수o를 가르킨다.
p는 프로토타입을 o로 가지는 오브젝트.
p.a = 12는 p에 새로운 a라는 속성을 만든다.
p.b = 의 this는 이제 o가아닌 p를 가르킨다. o함수의 b를 상속받아 개인 속성이라 할 수 있다.
프로토타입을 사용하는 방법
function doSomething(){};
var doSomething = function(){};
두 실행문을 파헤쳐보면 (객체 console.log(doSomethis.prototype) 해보면) 아래와 같다.
{
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
function doSomething(){}
doSomething.prototype.foo = "bar";
console.log( doSomething.prototype );
|
V
{
foo: "bar",
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
위코드결과는 프로토타입에 속성을 추가한것.
아래는 객체에 추가하는 것.
함수로 정의된건 new 통해 함수의 객체(인스턴스)를 만들 수 있다. 이를 통해 속성들을 이 객체에 추가한다.
function doSomething(){}
var doSomeInstancing = new doSomething();
doSomeInstancing.prop = "aaa"; //객체에 속성 추가
console.log( doSomeInstancing );
|
V
{
prop: "aaa",
__proto__: {
foo: "bar",
constructor: ƒ doSomething(), // -------doSomething.prototype();---------
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),
isPrototypeOf: ƒ isPrototypeOf(),
propertyIsEnumerable: ƒ propertyIsEnumerable(),
toLocaleString: ƒ toLocaleString(),
toString: ƒ toString(),
valueOf: ƒ valueOf()
}
}
}
함수 doSomethig의 prototype이 객체 doSomeInstancing에 연결되고 이 doSomeInstancing(doSomethig의 object)가
가지는 기본 속성(constructor , __proto__)은 함수 doSomethig을 연결한다.
doSomeInstancing.prop: aaa
doSomeInstancing.foo: bar
doSomething.prop: undefined
doSomething.foo: undefined
doSomething.prototype.prop: undefined
doSomething.prototype.foo: bar
function f(){ //함수 속성 a,b 갖는다
this.a =[];
this.b =[];
}
f.prototype = { //함수 f의 프로토타입에 속성a에 값을 추가
adda: function(v){
this.a.push(v);
}
}
};
var g = new f(); //함수 f의 오브젝트 생성 똑같이 a,b속성을 가지는 객체가 된다.
즉 , g.prototype = f.prototype
상속과 프로토타입 - JavaScript | MDN (mozilla.org)
http://dannyzhang.run/2017/04/06/Advanced-JavaScript-Objects-and-Functions/
자세한 공부를 위한 링크!