그 당시 지식을 실제로 이해할 수 없다면, 한동안 놓아서 미래에 남겨두면 이해할 수 있습니다.
몇 달 전, 나는 "JavaScript Advanced Programming (Third Edition)"을 보유하고 있었고 물체를 만드는 것을 씹은 후 상속을 씹기 시작했습니다. 그러나, 프로토 타입 체인을 씹은 후, 나는 더 이상 그것을 참을 수 없었고, 내 마음은 점점 더 지저분 해졌으므로 그것을 옆으로 던져서 후자를 계속 보았다. 이번 여름 휴가를 사용 하여이 상속을 이해 했으므로 메모를 정리하겠습니다.
프로토 타입 체인
먼저 기사를 읽어 보겠습니다. 이 기사의 저자는 매우 훌륭하고 고화질 사진이 장착되어 있습니다. ㅋㅋㅋ…
링크 : [연구 노트] 작은 관점에서 JS 프로토 타입 체인보기
원본 텍스트에서 몇 마디
프로토 타입과 인스턴스의 관계를 결정하십시오
프로토 타입과 인스턴스의 관계를 감지하는 두 가지 방법이 있습니다.
인스턴스 : 객체가 다른 개체의 인스턴스인지 결정합니다.
인스턴스의 내부 컴퓨팅 메커니즘은 다음과 같습니다.
functionInstance_of (l, r) {// l 왼쪽 표현식을 나타내고 R은 오른쪽 표현식 Varo = R.Prototype을 나타냅니다. // r l = l .__ proto__의 디스플레이 프로토 타입을 가져옵니다. // l while (true) {if (l === null) returnfalse; if (o === l) // 여기서 요점 : O가 l과 엄격하게 동일 할 때, truereturntrue를 반환합니다. l = l .__ proto__; }}위의 코드는 발췌 한 내용 : JavaScript Operator의 심도 분석
isprototype () : 객체가 다른 객체의 프로토 타입 체인에 존재하는지 테스트합니다.
이 두 가지 방법의 차이점을 참조하십시오 : JavaScript isprototyp vs instanceof usage
상속을 달성하기 위해 프로토 타입 체인 만 사용하십시오
단점 : 1. 유형 값을 참조하는 프로토 타입 속성은 인스턴스에서 공유됩니다. 2. 하위 유형의 인스턴스를 생성 할 때 매개 변수를 슈퍼 타입 생성자로 전달할 수 없습니다.
functionfather () {this.name = "아버지"; this.friends = [ 'aaa', 'bbb'];} functionson () {} son.prototype = newfather (); son.prototype.constructor = son; vars1 = newson (); vars2 = newson (); console.log (s1.name); // ratcherconsole.log (s2.name); // fathers1.name = "son"; console.log (s1.name); // sonconsole.log (s2.name); // ahroinconsole.log (s1.friends); // [ "aaa", "bbb"] console.log (s2. friffers); "bbb"] s1.friends.push ( 'ccc', 'ddd'); console.log (s1.friends); // [ "aaa", "bbb", "ccc", "ddd"] console.log (s2. friends); // [ "aaa", "bbb", "ccc", "ddd"]상속을 달성하기 위해 생성자 만 사용하십시오
구현 방법 : 하위 유형 생성자 내부의 SuperType 생성자를 호출합니다 (apply () 및 call () 메서드 사용)
장점 : 프로토 타입에서 유형 속성을 참조하는 문제를 해결하고 서브 클래스는 매개 변수를 슈퍼 클래스로 전달할 수 있습니다.
단점 : 서브 클래스 인스턴스는 부모 클래스 (슈퍼 클래스) 프로토 타입에 정의 된 메소드에 액세스 할 수 없으므로 기능 재사용에 대해 이야기 할 방법이 없습니다.
functionfather (이름, 친구) {this.name = name; this.wriends = friends = friends;} 아버지 .protopty.getname = function () {returnthis.name;}; functionson (name) {// 참고 : 아버지 구성자가 아들의 속성을 상환하지 않도록 아버지 생성자를 부르는 코드를 아들 제작자의 속성을 상환하지 않도록합니다. 아버지 .call (this, name, [ 'aaa', 'bbb']); this.age = 22;} vars1 = newson ( 'son1'); vars2 = newson ( 'son2'); console.log (s1.name); // son1console.log (s2.name); // son2s1.friends.push ( 'ccc', 'ddd'); console.log (s1.friends); // [ "aaa", "bbb", "ccc", "ddd"] console.log (s2.friends); // [ "aaa", "bbb"]; // typeError : s1.getName은 functions2.getName ()이 아닙니다. // typeError : s2.getName은 함수가 아닙니다조합 상속
구현 방법 : 프로토 타입 체인을 사용하여 프로토 타입 속성 및 방법의 상속을 구현하고 생성자를 사용하여 인스턴스 속성의 상속을 구현하십시오.
functionfather (이름, 친구) {this.name = name; this.wriends = friends = friends;} ritoy..prototyp.money = "100k $"; 아버지 .prototype.getName = function () {console.log (this.name);}; functionson (이름, age) {// 부모 등급의 속성을 상주합니다. 아버지. = Newson ( 'son1', 12); s1.friends.push ( 'ccc'); console.log (s1.friends); // [ "aaa", "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getName (); // son1s1.getage (); // 12vars2 = newson ( 'son2', 24); console.log (s2.friends); // [ "aaa", "bbb"] console.log (s2.money); // 100k $ s2.getName (); // son2s2.getage (); // 24조합 상속은 프로토 타입 체인 또는 생성자를 사용하여 일방적으로 상속을 구현하고, 장점을 결합하며, JavaScript에서 가장 일반적으로 사용되는 상속 모델이되지만 결함이 있으며 조합 상속의 결함은 나중에 언급 될 것입니다.
프로토 타입 상속
구현 아이디어 : 프로토 타입을 사용하여 이로 인해 사용자 정의 유형을 만들지 않고 기존 객체를 기반으로 새 개체를 만듭니다.
이를 달성하기 위해 다음 기능 (OBJ)이 도입됩니다
functionObj (o) {functionf () {} f.prototype = o; returnnewf ();} varperson1 = {이름 : "percy", 친구 : [ 'aaa', 'bbb']}; varperson2 = obj (person1); person.1); person2.name = "zyj"; personefriffe.name ( 'ccc'); percyconsole.log (person.2.name); // zyjconsole.log (person1.friends); // [ "aaa", "bbb", "ccc"] console.log (person2.friends); // [ "aaa", "bbb", "ccc"] ecmastance versional을 추가로 추가하여 herittomate () 매개 변수를 전달하는 경우 Object.create () 및 obj () 메소드가 동일하게 행동합니다. varperson1 = {name : "percy", 친구 : [ 'aaa', 'bbb']}; varperson2 = 객체. zyjconsole.log (person1.friends); // [ "aaa", "bbb", "ccc"] console.log (person2.friends); // [ "aaa", "bbb", "ccc"]이 상속은 생성자를 동원하여 생성을 생성 할 필요가 없을 때 선택할 수 있지만, 한 개체가 다른 개체와 비슷하게 유지되기를 원합니다.
기생 상속
기생 상속은 프로토 타입 상속과 밀접한 관련이있는 아이디어입니다.
구현 아이디어 : 상속 프로세스를 캡슐화하는 데만 사용되는 함수를 만듭니다.이 프로세스는 내부적으로 객체를 어떤 식 으로든 향상시키고 마지막으로 객체를 반환합니다.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functionCreatePerson (Original) {// 상속 공정 캡슐화 varclone = obj (Original); // 개체 clone.showsomething = function () {// enterance object console.log ( "hello world!"); . // Hello World!기생 조합 상속
먼저 이전 조합 상속의 단점에 대해 이야기합시다. 조합 상속의 가장 큰 문제는 상황이 무엇이든 상관없이 부모 클래스의 생성자가 두 번 불려질 것이라는 점입니다. 하나는 서브 클래스의 프로토 타입을 만들 때, 다른 하나는 서브 클래스 생성자를 호출 할 때, 부모 클래스의 생성자는 서브 클래스 생성자 내부에서 호출됩니다.
functionfather (이름, 친구) {this.name = name; this.wriends = friends = friends;} ritoy..prototyp.money = "100k $"; 아버지 .prototype.getName = function () {console.log (this.name);}; functionson (이름, age) {// 부모 등급의 속성을 상주합니다. 아버지 .call (this, name, [ 'aaa', 'bbb']); // 아버지에 대한 두 번째 호출 ()은 실제로 this.age = age;} // 부모 클래스 프로토 타입의 속성과 방법을 상속받습니다. prototype = newfather (); // 처음 아버지 ()는 son.prototype.constructor = son;첫 번째 호출은 서브 클래스의 프로토 타입을 부모 클래스의 인스턴스로 만들어 서 서브 클래스의 프로토 타입이 부모 클래스의 인스턴스 속성을 얻습니다. 두 번째 호출은 서브 클래스의 인스턴스 속성이 부모 클래스의 인스턴스 속성을 얻게합니다. 서브 클래스의 인스턴스 속성은 기본적으로 서브 클래스 프로토 타입으로 복제 된 속성을 차단합니다. 따라서,이 두 통화 후, 불필요한 속성은 서브 클래스 프로토 타입에 나타나서이 문제를 해결하기위한 기생 조합 상속을 도입합니다.
기생 조합 상속의 아이디어는 다음과 같습니다. 서브 클래스의 프로토 타입을 지정하기 위해 부모 클래스 생성자를 호출 할 필요가 없습니다. 우리에게 필요한 것은 부모 클래스 프로토 타입의 사본입니다.
기본적으로 기생 상속을 사용하여 부모 클래스의 프로토 타입을 물려받은 다음 결과를 아동 클래스의 프로토 타입으로 되돌려 놓는 것입니다.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functionInHeritPrototype (SON, 아버지) {varPrototype = obj (austry.prototyp); // 객체 프로토 타입 생성 .constructor = son; // 개체 향상 SON.PROTOTYP = 프로토 타입; // return object} functionfather (이름, 친구) {this.name = name; this.friends = friender;} ritoy.priends;} ritoy.getname = function () {console.log (this.name);}; functionson (name, age) {// 부모 클래스의 속성 아버지 .call (this, name, [ 'aaa', 'bbb']); this.age = age;} // 상위 클래스 프로토 타입의 특성과 방법을 상속합니다. inheritPrototype (아들, 아버지); son.prototype.getage = function () {console.log (this.ge);}; varson ( 'son1', 12); s1.friffles.push ( 'ccc'); " "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getName (); // son1s1.getage (); // 12vars2 = newson ( 'son2', 24); console.log (s2.friends); // [ "aaa", "bbb"] console.log (s2.money); // 100k $ s2.getName (); // son2s2.getage (); // 24장점 : 서브 클래스 프로토 타입으로 부모 클래스에서 불필요한 인스턴스 속성을 상속하지 않도록합니다.
개발자들은 일반적으로 기생 조합 상속이 유형 상속을 기반으로하는 가장 이상적인 상속 방법이라고 생각합니다.
마침내
마지막으로 두 개의 매우 어려운 기사를 강력히 추천합니다
JavaScript 프로토 타입 상속이 실제로 어떻게 작동하는지
JavaScript의 의사 클래식 상속 다이어그램 (벽을 가로 지르는 필요)
두 번째 기사에서 어려운 사진을 찍습니다.
그것을 읽은 후, 나는 몇 초 만에 프로토 타입 체인을 이해합니다. 뭔가 있어요?
위는 JavaScript가 상속받은 정보의 모음입니다. 우리는 향후 관련 정보를 계속 추가 할 것입니다. 이 웹 사이트를 지원 해주셔서 감사합니다!