이 글에서는 주로 JavaScript 기생 결합 상속을 소개합니다. 기생 결합 상속의 원리, 구현 방법 및 관련 주의 사항을 예제와 함께 자세히 분석합니다. 도움이 필요한 친구들은 참고할 수 있습니다.
이 글의 예제에서는 JavaScript 기생 결합 상속이 설명되어 있습니다. 참고를 위해 자세한 내용을 공유합니다.
사실 "JavaScript Advanced 프로그래밍"이라는 책에 이미 완전한 코드가 나와 있습니다. 코드를 이해하면 이 상속이 무엇인지 알 수 있습니다.
먼저 js에는 객체의 속성을 정의하는 두 가지 방법이 있습니다.
//通过执行构造函数设置属性 function A(){ this.a = 1; } //通过原型设置属性 A.prototype.b = 1;
그래서:
Sub 클래스가 다른 클래스 Super를 상속하려면 상위 클래스의 프로토타입 아래에 있는 속성을 상속해야 합니다. , 부모 클래스의 생성자도 실행합니다.
즉, Sub 클래스가 다른 Super 클래스를 상속하려면 프로토타입 체인을 통해 프로토타입 속성과 메서드를 상속해야 할 뿐만 아니라 하위 클래스 생성자 내에서 상위 클래스 생성자를 호출하여 인스턴스 속성도 상속해야 합니다.
1. 프로토타입 아래의 속성 상속위에서 볼 수 있듯이 Super 클래스의 프로토타입 아래 속성은 상속되지 않으므로 이 부분을 아래에 상속해야 합니다.
Direct "="는 확실히 작동하지 않습니다. 왜냐하면 Sub.prototype의 속성을 수정한 후에는 Super.prototype의 객체에 영향을 미칠 수 없기 때문입니다. 즉, Sub.prototype=Super.prototype
할 수 없습니다. .
먼저 객체의 복사본을 생성하는 메소드를 작성하세요Sub.prototype=Super.prototype
。
首先写一个创建对象副本的方法
function object(o){ function A(){} A.prototype = o var ox = new A() return ox }
上面的函数得到的对象ox,拥有了对象o的全部属性(在原型链上),而修改ox的属性,不会影响到o,相当于把o复制了一份。
原型式继承就是上面的“object”函数,在很多类库源码中都能发现它的身影
简单而言,原型式继承就是不用实例化父类了,直接实例化一个临时副本实现了相同的原型链继承。(即子类的原型指向父类副本的实例从而实现原型共享)
tips:总所周知,原型链继承是子类的原型指向父类的实例从而实现原型共享,而原型式继承是子类的原型指向父类副本的实例从而实现原型共享。
ECMAScirpt 5通过新增Object.create()
方法规范化了原型式继承。
使用object方法,就可以将Super.prototype的属性「复制」到Sub.prototype上了,当然这儿还需要修正一下constructor的指向。
function inherit(subType,superType){ var prototype=Object.create(superType.prototype); prototype.constructor=subType; subType.prototype=prototype; }
2. 分别执行父类和子类的构造函数,继承这部分下的属性:
//父类 function Super(){ this.sss=1 } //子类 function Sub(){ //arguments是Sub收到的参数,将这个参数传给Super Super.apply(this, arguments) } //实例 sub = new Sub()
Super.apply(this, arguments)
这一句,将Super类作为一个普通函数来执行,但是Super类的this被换成了Sub类的this,Sub收到的参数也传给了Super
最后执行结果相当于sub.sss=1
附上各种继承方式的特点和优缺点
曾经一段时间因为javascript关于类实现继承的不规范,导致各种各样实现继承的代码;而实际上不管代码怎么变,继承都基于两种方式:
1.通过原型链,即子类的原型指向父类的实例从而实现原型共享。
2.借用构造函数,即通过js的apply、call实现子类调用父类的属性、方法;
原型链方式可以实现所有属性方法共享,但无法做到属性、方法独享(例如Sub1修改了父类的函数,其他所有的子类Sub2、Sub3...想调用旧的函数就无法实现了);
而借用构造函数除了能独享属性、方法外还能在子类构造函数中传递参数,但代码无法复用。总体而言就是可以实现所有属性方法独享,但无法做到属性、方法共享(例如,Sub1新增了一个函数,然后想让Sub2、Sub3...都可以用的话就无法实现了,只能Sub2、Sub3...各自在构造函数中新增)。
组合继承就是把以上两种继承方式一起使用,把共享的属性、方法用原型链继承实现,独享的属性、方法用借用构造函数实现,所以组合继承几乎完美实现了js的继承;为什么说是“几乎”?因为认(dan)真(teng)的geek们发现组合继承有一个小bug,实现的时候调用了两次超类(父类),性能上不合格啊有木有!怎么解决呢?于是“寄生继承”就出来了。
寄生继承(原型式继承)就是不用实例化父类了,直接实例化一个临时副本实现了相同的原型链继承。(即子类的原型指向父类副本的实例从而实现原型共享)
“寄生组合继承”用了“寄生继承”修复了“组合继承”的小bug,从而让js完美实现继承了。
实例代码:
function SuperType(name,colors){ this.name=name; this.colors=colors; } SuperType.prototype.getSuperProperty=function(){ return this.name; } function SubType(job,name,colors){ SuperType.call(this,name,colors); this.job=job; } SubType.prototype.getSubPrototype=function(){ return this.job; } function inherit(subType,superType){ var prototype=Object.create(superType.prototype); prototype.constructor=subType; subType.prototype=prototype; } inherit(SubType,SuperType); var instance=new SubType("doctor","John",["red","green"]); console.log(instance.getSubPrototype()); //输出"doctor" console.log(instance.getSuperProperty()); //输出"John",成功调用在父类原型定义的方法
属性继承代码是SuperType.call(this,name,colors);
原型继承代码是inherit(SubType,SuperType);
rrreee
Object.create()
메서드를 추가하여 프로토타입 상속을 표준화합니다. 🎜🎜객체 메서드를 사용하면 Super.prototype의 속성을 Sub.prototype으로 "복사"할 수 있습니다. 물론 여기서 생성자의 지정도 수정해야 합니다. 🎜rrreee🎜🎜2. 상위 클래스와 하위 클래스의 생성자를 각각 실행하고 다음 부분의 속성을 상속합니다. 🎜🎜rrreee🎜Super.apply(this, 인수)
이 문장에서는 다음을 사용합니다. 일반 함수인 Super 클래스가 실행되는데 Super 클래스의 this가 Sub 클래스의 this로 대체되고 Sub에서 받은 매개변수도 Super에 전달됩니다🎜🎜최종 실행 결과는 sub.sss=1과 같습니다. 🎜🎜🎜다양한 상속을 첨부합니다. 메소드의 특징, 장점, 단점🎜🎜🎜JavaScript가 클래스 구현 상속에 대해 표준화되지 않아 상속을 구현하는 코드가 다양해지던 시절이 있었지만 실제로는 코드가 어떻게 바뀌든 상관이 없습니다. , 상속은 두 가지 방법을 기반으로 합니다.🎜🎜🎜 1. 프로토타입 체인🎜을 통해, 즉 하위 클래스의 프로토타입이 상위 클래스의 인스턴스를 가리켜 프로토타입 공유를 달성합니다. SuperType.call(this,name,colors);
입니다.🎜🎜프로토타입 상속 코드는 inherit(SubType,SuperType);
입니다. code> 🎜🎜위 내용은 앞으로 모든 분들에게 도움이 되기를 바랍니다. 🎜🎜관련 기사: 🎜
Angular1에서 gulp 및 Bower와 함께 사용하는 방법은 무엇입니까?
위 내용은 JavaScript를 사용하여 기생 구성 가능 상속을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!