JavaScript 상속에 대한 설명이 합의되었지만 지연되었습니다. 더 이상 고민하지 않고 요점에 도달하십시오.
상속을 이해하기를 원하기 때문에 이미 JavaScript 객체 지향에 대한 특정 이해가 있음을 증명합니다. 아무것도 이해하지 못하면 객체 지향 JS, 팩토리 모드, 생성자 모드, 프로토 타입 모드, 혼합 모드, 동적 프로토 타입 모드에 대한 기본 설명을 참조 할 수 있습니다. 다음, 일반적으로 해당 방법을 통해 JavaScript의 상속에 대해 이야기 해 봅시다.
프로토 타입 체인
JavaScript에서 상속을 구현하는 가장 쉬운 방법은 프로토 타입 체인을 사용하고 자식 유형의 프로토 타입을 부모 유형의 인스턴스, 즉 "subtype.prototype = new Parent Type ();" 구현 방법은 다음과 같습니다.
// 생성자 함수 생성 superType () {this.name = [ 'wuyuchang', 'jack', 'tim']; this.property = true;} // 메소드 add supertype.prototype.getSuerValue = function () {return this.property;} // 생성자 함수 subtype () {this.test = [ 'h1', 'h2', 'h3', 'h4']; this.subproperty = false;} // 상속을 구현하기위한 주요 단계, 하위 유형의 프로토 타입은 부모 유형 subtype.prototype = new supttype ()의 인스턴스를 가리 킵니다. 상속이 구현 된 후에야합니다. 그렇지 않으면 포인터가 상위 유형의 인스턴스를 가리키고 메소드가 비어 있습니다. subtype.prototype.getSubvalue = function () {return this.subproperty;}/* 다음은 테스트 코드 예제*/var instance1 = new subtype (); instance1.name.push ( 'wyc'); instance1.test.push ( 'h5'); alert (instans1.getsuervalue ()); // truealert (instance1.getSubvalue ()); // falsealert (instance1.name); // Wuyuchang, Jack, Tim, Wycalert (instance1.test); // h1, h2, h3, h4, h5var instance2 = new subtype (); alert (instance2.name); // Wuyuchang, Jack, Tim, Wycalert (instance2.test); // H1, H2, H3, H4위의 코드는 프로토 타입 체인을 통해 구현 된 간단한 상속임을 알 수 있지만 여전히 테스트 코드 예제에는 몇 가지 문제가 있습니다. 블로그 게시물을 읽은 후 "객체 지향 JS, 공장 모드, 생성자 모드, 프로토 타입 모드, 혼합 모드, 동적 프로토 타입 모드의 기본 설명"을 읽은 후에 는 프로토 타입 체인 코드의 첫 번째 문제는 하위 유형의 프로토 타입이 부모 유형의 인스턴스라는 것입니다. 모든 인스턴스에서 공유합니다 . 인스턴스 1.name.push ( 'Wyc'); 위의 코드 중에서이 문제의 존재를 증명할 수 있습니다. 프로토 타입 체인의 두 번째 문제는 하위 유형의 인스턴스를 만들 때 매개 변수를 슈퍼 유형 생성자로 전달할 수 없다는 것입니다. 따라서 실제 개발에서는 프로토 타입 체인 만 사용하지 않습니다.
생성자를 빌리십시오
프로토 타입 체인에서 두 가지 문제를 해결하기 위해 개발자는 차용 생성자라는 기술을 사용하여 프로토 타입 체인의 문제를 해결하기 시작했습니다. 이 기술의 구현 아이디어도 매우 간단합니다. 하위 유형의 생성자 내에서 부모 유형의 생성자 만 호출하면됩니다. 함수는 특정 환경에서 코드를 실행하는 객체이므로 Apply () 또는 Call () 메소드를 통해 생성자를 실행할 수 있습니다 . 코드는 다음과 같습니다.
// 생성자 함수 생성 SuperType (name) {this.name = name; this.color = [ '분홍색', '옐로우']; this.property = true; this.testfun = function () {alert ( 'http://tools.vevb.com/'); }} // 메소드 추가 SuperType.prototype.getSuerValue = function () {return this.property;} // 생성자 함수 subtype (name) {superType.call (this, name); this.test = [ 'h1', 'h2', 'h3', 'h4']; this.subproperty = false;} // 여기에서 하위 유형에 메소드를 추가합니다. 상속을 구현하십시오. 그렇지 않으면 포인터가 상위 유형의 인스턴스를 가리키며 메소드는 빈 하위 유형 .prototype.getSubvalue = function () {return this.subproperty;}/* 테스트 코드 예제입니다*/var instance1 = new subtype ([ 'wuyuchang', 'jack', 'jack', 'jack', 'nick']); instance1.name.push ( 'hello'); instance1.test.push ( 'h5'); instance1.color.push ( 'blue'); instance1.testfun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, Hello // alert (instance1.getSuerPerValue ()); // Error Alert (instance1.test); // H1, H2, H3, H4, H5 ALERT (instance1.getSubValue ()); // false alert (instance1.color); // 핑크, 노란색, bluevar instance2 = new subtype ( 'wyc'); instance2.testfun (); // http://tools.vevb.com/alert(instance2.name); // wyc // alert (instance2.getSuerperValue ()); // error alert (instance2.test); // h1, h2, h3, h4alert (instance2.getSubvalue ()); // falsealert (instance2.Color); // 분홍색, 노란색위의 코드에서 위 코드에서 하위 유형 하위 유형의 생성자 인 위의 코드에서는 부모 유형을 "supertype.call (this, name)"을 호출하여 속성의 상속이 실현된다는 것을 알 수 있습니다. 하위 유형이 생성 될 때 매개 변수를 부모 유형으로 전달할 수도 있지만 새로운 문제가 발생합니다. 부모 유형의 생성자 (testfun)의 메소드와 부모 유형의 프로토 타입에서 메소드를 정의했음을 알 수 있습니다 : getsupervalue. 그러나 하위 유형을 인스턴스화 한 후에도 부모 유형의 프로토 타입에 정의 된 메소드 getSuperValue를 호출하는 것은 여전히 불가능하며 , 부모 유형 : TestFun에서 생성자의 메소드 만 호출 할 수 있습니다. 이는 객체를 만드는 데 생성자 모드 만 사용하여 기능에 재사용 가능성이 없습니다. 이러한 문제를 고려하여 빌린 생성자 기술은 거의 사용되지 않습니다.
조합 상속 (프로토 타입 체인 + 차용 생성자)
이름에서 알 수 있듯이, 조합 상속은 프로토 타입 체인의 사용과 빌린 생성자의 사용을 결합하는 장점으로 구성된 패턴이다. 구현도 매우 간단합니다. 물론 그것은 조합이기 때문에 양 당사자의 장점, 즉 프로토 타입 체인 상속 방법과 생성자는 속성을 상속합니다 . 특정 코드는 다음과 같이 구현됩니다.
// 생성자 함수 생성 SuperType (name) {this.name = name; this.color = [ '분홍색', '옐로우']; this.property = true; this.testfun = function () {alert ( 'http://tools.vevb.com/'); }} // 메소드 추가 SuperType.prototype.getSuerValue = function () {return this.property;} // 생성자 함수 subtype (name) {superType.call (this, name); this.test = [ 'h1', 'h2', 'h3', 'h4']; this.subproperty = false;} subtype.prototype = new supertype (); // 여기에서 하위 유형에 메소드를 추가합니다. 상속이 구현 된 후에야, 그렇지 않으면 포인터가 상위 유형의 인스턴스를 가리키며 메소드는 빈 하위 유형. 'nick']); instance1.name.push ( 'hello'); instance1.test.push ( 'h5'); instance1.color.push ( 'blue'); instance1.testfun (); // http://tools.vevb.com/alert(instance1.name); // Wuyuchang, Jack, Nick, HelloAlert (instance1.getSuerPerValue ()); // truealert (instance1.test); // H1, H2, H3, H4, H5 ALERT (instance1.getSubValue ()); // false alert (instance1.color); // 핑크, 노란색, bluevar instance2 = new subtype ( 'wyc'); instance2.testfun (); // http://tools.vevb.com/alert(instance2.name); // WYC ALERT (instance2.GetSuerPerValue ()); // truealert (instance2.test); // h1, h2, h3, h4alert (instance2.getSubvalue ()); // falsealert (instance2.Color); // 분홍색, 노란색위의 코드는 SuperType.call (this, name)을 통해 상위 유형의 속성을 상속합니다. 하위 유형을 통해 부모 유형의 방법을 상속합니다. proToptyp = new supttype ();. 위의 코드는 프로토 타입 체인 및 차용 생성자가 발생하는 문제를 편리하게 해결하며 JavaScript에서 가장 일반적으로 사용되는 인스턴스 상속 방법이되었습니다. 그러나 혼합 모드는 단점이 없습니다. 위의 코드에서 메소드를 상속 할 때 상위 유형의 속성이 실제로 상속되었음을 알 수 있습니다. 그러나 현재 참조 유형은 공유됩니다. 따라서, 상위 유형의 생성자는 하위 유형 이후 자식 유형의 생성자에서 호출되므로, 부모 유형의 속성을 상속하여 프로토 타입에서 상속 된 속성을 덮어 씁니다. 생성자를 두 번 호출 할 필요는 없지만 해결할 방법이 있습니까? 이 문제를 해결할 때 먼저 다음 두 모드를 살펴보십시오.
프로토 타입 상속
프로토 타입 상속의 구현 방법은 일반적인 상속의 구현 방법과 다릅니다. 프로토 타입 상속은 엄격한 의미에서 생성자를 사용하지 않고 대신 프로토 타입을 사용하여 기존 객체를 기반으로 새 객체를 생성하므로 결과적으로 사용자 정의 유형을 만들 필요가 없습니다. 특정 코드는 다음과 같습니다.
함수 객체 (o) {function f () {} f.prototype = O; 새로운 f ();} 반환Code example:
/* 프로토 타입 상속*/함수 객체 (o) {function f () {} f.prototype = O; return new f ();} var person = {이름 : 'Wuyuchang', 친구 : [ 'wyc', 'nicholas', 'tim']} var otherperson = object (person); 다른 사람 .name = 'Greg'; 다른 사람 .Friends.push ( 'bob'); var agerperson2 = Object (person); exerperson2.name = 'jack'; otherperson2.friends.push ( 'Rose'); Alert (person.friends); // Wyc, Nicholas, Tim, Bob, Rose기생 상속
/* 기생 상속 물*/기능 CreateAnother (원본) {var clone = Object (Original); clone.sayhi = function () {alert ( 'hi'); } 반환 클론;}사용의 예 :
/* 프로토 타입 상속*/함수 객체 (o) {function f () {} f.prototype = O; 새로운 f ();} /* 기생 상속을 반환합니다* /함수 createanother (Original) {var clone = Object (Original); clone.sayhi = function () {alert ( 'hi'); } 반환 클론;} var person = {name : 'wuyuchang', 친구 : [ 'wyc', 'nicholas', 'rose']} var 다른 사람 = createanother (person); 다른 사람 .sayhi ();기생 조합 상속
이전에 JavaScript에서 상속의 조합 패턴 구현의 단점을 언급했습니다. 이제 단점을 해결해 봅시다. 구현 아이디어는 생성자의 속성을 상속하는 것이며, 프로토 타입 체인의 혼합 형태 상속 방법은 방법을 상속 할 때 부모 유형의 생성자를 인스턴스화 할 필요가 없습니다. 코드는 다음과 같습니다.
함수 객체 (o) {function f () {} f.prototype = O; return new f ();}/* 기생 조합 상속*/함수 inheritPrototype (subtype, superType) {var prototype = object (superType.prototype); 프로토 타입 .constructor = 하위 유형; subtype.prototype = 프로토 타입;}이를 사용할 때는 코드 라인 "subtype.prototype = new supttype ();"만 교체하면됩니다. 상속 프로토 타입 (서브 타입, SuperType)을 갖는 조합 모드에서. 기생 조합 상속의 효율성은 불필요하거나 중복 된 특성의 생성을 피하면서 부모 유형 생성자를 한 번만 호출한다는 점에 반영됩니다. 동시에, 프로토 타입 체인은 변경되지 않은 상태로 유지 될 수 있으므로 인스턴스와 isprototype ()도 정상적으로 사용할 수 있습니다. 이것은 또한 현재 가장 이상적인 상속 방법이며 현재이 모델로 변환되고 있습니다. (Yui 도이 모드를 사용합니다.)
이 블로그 게시물은 "JavaScript Advanced Programming 3rd Edition"을 나타냅니다. 이 코드는 다시 작성되고 더 구체적이며 모든 사람이 이해하기 쉽도록 댓글을 달았습니다. JS 상속에 대한 독특한 통찰력이 있다면 인색하지 마십시오. 참조에 대한 귀하의 의견에 답장하십시오!