javascript 계승의 6대 모드 소결

9511 단어
1. 원형 체인

function SuperType(){
this.property = true;
}

SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
// SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true


실현의 본질은 원형 대상을 다시 쓰고 새로운 유형의 실례를 대신하는 것이다.
2. 구조 함수 대여

function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
// SuperType
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green"


만약 구조 함수만 빌려쓴다면 구조 함수 모델에 존재하는 문제점을 피할 수 없을 것이다. 방법은 모두 구조 함수에 정의되어 있기 때문에 함수 복용은 말할 수 없다.그리고 초유형의 원형에 정의된 방법은 하위 유형에도 보이지 않고 결과적으로 모든 유형은 구조 함수 모드만 사용할 수 있다.이런 문제들을 감안하면 구조 함수를 빌려쓰는 기술도 단독으로 사용하는 경우는 드물다.
3. 조합 승계

function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);

};
function SubType(name, age){
// 
SuperType.call(this, name);
this.age = age;
}
// 
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27


이 예에서 SuperType 구조 함수는 두 가지 속성을 정의했다:name와colors.SuperType의 원형은 sayName() 방법을 정의합니다.SubType 구조 함수는 SuperType 구조 함수를 호출할 때name 매개 변수를 전송하고 그 다음에 자신의 속성age를 정의합니다.그런 다음 SuperType의 인스턴스를 SubType의 원형에 지정하고 새 원형에 방법sayAge()를 정의합니다.이렇게 하면 두 개의 서로 다른 SubType 실례가 각각 자신의 속성인 컬러스 속성을 포함하고 같은 방법을 사용할 수 있게 된다.
조합 계승은 원형 체인과 차용 구조 함수의 결함을 피하고 그들의 장점을 융합시켜 자바스크립트에서 가장 자주 사용하는 계승 모델이 되었다.그리고 instanceof와 isPrototypeOf()도 조합 계승을 바탕으로 만든 대상을 식별하는 데 사용할 수 있다.
4. 원형 계승

function object(o){
function F(){}
F.prototype = o;
return new F();
}


object () 함수 내부에서 임시적인 구조 함수를 만든 다음에 전송된 대상을 이 구조 함수의 원형으로 하고 마지막으로 이 임시 형식의 새로운 실례를 되돌려줍니다.본질적으로 말하자면object () 는 그 안에 들어온 대상에 대해 얕은 복사를 실행했다.아래의 예를 보아라.

var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"

크록포드가 주장하는 이런 원형식 계승은 당신이 반드시 다른 대상이 될 수 있는 기초가 있어야 한다고 요구한다.만약 이런 대상이 있다면object () 함수에 전달하고 구체적인 수요에 따라 얻은 대상을 수정하면 된다.이 예에서 다른 대상의 기초가 될 수 있는 것은person 대상이다. 그래서 우리는object () 함수에 그것을 전달하고 이 함수는 새로운 대상을 되돌려준다.이 새 대상은person을 원형으로 하기 때문에 그 원형에는 기본 형식 값 속성과 인용 형식 값 속성이 포함되어 있습니다.이것은 사람을 의미한다.friends는 개인 소유일 뿐만 아니라 another Person과 yet Another Person에게도 공유된다.실제로 이것은 또 개인 대상의 두 개의 사본을 만든 것과 같다.
ECMAScript 5는 새 개체를 통해 생성됩니다.create () 방법은 원형식 계승을 규범화했다.이 방법은 두 개의 매개 변수를 수신합니다. 하나는 새로운 대상의 원형으로 사용되는 대상과 하나는 새로운 대상에 추가 속성을 정의하는 대상입니다.매개변수가 전송된 경우 Object.create () 는 object () 방법과 동작이 같습니다.

var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"

Object.create () 메서드의 두 번째 매개변수와 Object.defineProperties () 방법의 두 번째 매개 변수 형식은 같습니다. 모든 속성은 자신의 설명자를 통해 정의됩니다.이러한 방식으로 지정된 모든 속성은 원형 대상의 동명 속성을 덮어씁니다.예:

var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};

var anotherPerson = Object.create(person, {
name: {
value: "Greg"
}
});
alert(anotherPerson.name); //"Greg"


Object 지원.create () 방법의 브라우저는 IE9+, Firefox 4+, Safari 5+, Opera 12+, Chrome입니다.
구조 함수를 창설할 필요가 없고, 한 대상이 다른 대상과 유사하게 유지하려는 상황에서 원형식 계승은 충분히 감당할 수 있다.그러나 인용 유형 값을 포함하는 속성은 시종 상응하는 값을 공유하는데 마치 원형 모델을 사용하는 것과 같다는 것을 잊지 마라.
5. 기생식 계승
기생식(parasitic) 계승은 원형식 계승과 밀접한 관계를 가진 사고방식이며 크록포드에서 널리 보급된 것이다.기생식 계승의 사고방식은 기생 구조 함수와 공장 모델과 유사하다. 즉, 계승 과정을 봉인하는 데만 사용되는 함수를 만드는 것이다. 이 함수는 내부에서 어떤 방식으로 대상을 강화하고 마지막에 정말로 모든 일을 한 것처럼 대상을 되돌려준다.다음 코드는 기생식 계승 모델을 시범하였다.

function createAnother(original){
var clone = object(original); // 
clone.sayHi = function(){ // 
alert("hi");
};
return clone; // 
}

이 예에서createAnother() 함수는 새로운 대상의 기초가 될 대상을 수신합니다.그리고 이 대상 (original) 을object () 함수에 전달하고 되돌아오는 결과를clone에 부여합니다.clone 대상에 새로운 방법sayHi () 를 추가하고 마지막으로 clone 대상을 되돌려줍니다.다음과 같이 createAnother() 함수를 사용할 수 있습니다.

var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"

이 예에서 코드는person을 바탕으로 새로운 대상인 anotherPerson을 되돌려줍니다.새로운 대상은person의 모든 속성과 방법을 가지고 있을 뿐만 아니라, 자신의sayHi() 방법도 가지고 있다.사용자 정의 유형과 구조 함수가 아닌 대상을 주로 고려하는 상황에서 기생식 계승도 유용한 모델이다.앞에서 계승 모드를 시범할 때 사용하는object () 함수는 필요하지 않습니다.새 대상을 되돌릴 수 있는 모든 함수는 이 모드에 적용됩니다.
기생식 계승을 사용하여 대상에 함수를 추가하면 함수 복용을 할 수 없기 때문에 효율이 떨어진다.이 점은 구조 함수 모델과 유사하다.
6. 기생 조합식 계승
앞에서 말했듯이 조합 계승은 자바스크립트에서 가장 자주 사용하는 계승 모델이다.하지만 그것도 자신의 부족함이 있다.조합 계승의 가장 큰 문제는 어떤 상황에서도 두 번의 초유형 구조 함수를 호출하는 것이다. 한 번은 하위 유형의 원형을 만들 때, 다른 한 번은 하위 유형 구조 함수 내부에 있다.맞아요. 하위 형식은 최종적으로 초형식 대상의 모든 실례 속성을 포함하지만, 하위 형식 구조 함수를 호출할 때 이 속성을 다시 써야 합니다.다음 그룹 상속의 예를 다시 한 번 봅시다.

function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name); // SuperType()
this.age = age;
}
SubType.prototype = new SuperType(); // SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};

굵은 글꼴을 넣은 줄에는 SuperType 구조 함수를 호출하는 코드가 있습니다.SuperType 구조 함수를 처음 호출할 때 SubType.프로토타입은 두 가지 속성을 얻을 수 있습니다:name와colors;그것들은 모두 SuperType의 실례 속성이며, 단지 현재 SubType의 원형에 있을 뿐이다.SubType 구조 함수를 호출할 때 SuperType 구조 함수를 호출합니다. 이번에는 새 대상에 실례 속성name과colors를 만들었습니다.그래서 이 두 속성은 원형 중의 두 개의 동명 속성을 차단했다.그림6-6은 상술한 과정을 보여 준다.그림6-6에서 보듯이 두 그룹의name와colors 속성이 있습니다. 한 그룹은 실례적으로, 한 그룹은 SubType 원형에 있습니다.이것이 바로 SuperType 구조 함수를 두 번 호출한 결과입니다.다행히도 우리는 이미 이 문제를 해결하는 방법을 찾았다. 기생 조합식 계승이다.
기생 조합식 계승이란 구조 함수를 빌려 속성을 계승하고 원형 체인의 혼성 형식을 통해 계승하는 방법이다.그 배후의 기본적인 사고방식은 하위 유형의 원형을 지정하기 위해 초유형의 구조 함수를 호출할 필요가 없다는 것이다. 우리가 필요로 하는 것은 초유형 원형의 사본일 뿐이다.본질적으로 기생식 계승을 사용하여 초유형의 원형을 계승한 다음에 결과를 하위 유형의 원형에 지정하는 것이다.기생 조합식 계승의 기본 모델은 다음과 같다.

function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); // 
prototype.constructor = subType; // 
subType.prototype = prototype; // 
}

이 예시의 inheritPrototype () 함수는 기생 조합식 계승의 가장 간단한 형식을 실현했다.이 함수는 두 개의 매개 변수를 수신합니다: 하위 유형 구조 함수와 초유형 구조 함수입니다.함수 내부에서 첫 번째 단계는 초유형 원형의 사본을 만드는 것이다.두 번째 단계는 생성된 복사본에 constructor 속성을 추가하여 원형을 다시 써서 잃어버린 기본적인constructor 속성을 보완하는 것입니다.마지막으로 새로 만든 대상(즉 복사본)을 하위 유형의 원형에 부여합니다.이렇게 하면 우리는 inherit-Prototype () 함수를 호출하는 문장으로 앞의 예에서 하위 유형의 원형에 값을 부여한 문장을 대체할 수 있다. 예를 들어

function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
};


이 예의 고효율은 SuperType 구조 함수를 한 번만 호출했기 때문에 SubType을 피할 수 있다는 데 나타난다.prototype에서 불필요한 속성을 만듭니다.이와 동시에 원형 체인은 변하지 않을 수 있다.따라서 instanceof와 isPrototypeOf()도 정상적으로 사용할 수 있습니다.개발자들은 보편적으로 기생 조합식 계승을 인용 유형의 가장 이상적인 계승 모델로 여긴다.
YUI의 YAHOO.lang.extend () 방법은 기생 조합 계승을 채택하여 이런 모델을 매우 광범위하게 응용되는 자바스크립트 라이브러리에 처음으로 등장시켰다.YUI에 대한 자세한 내용을 보려면http://developer. yahoo.com/yui/.
상기에서 말한 것이 본고의 전체 내용입니다. 여러분이javascript 계승을 배우는 데 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기