继承
继承的本质就是复制,即重写原型对象,代之以一个新类型的实例。
function parentClass(name){
this.name = name;
}
function sonClass(){
}
1.原型链继承
sonClass.prototype = new parentClass();
缺点:
- 不能向构造函数传参
- 引用类型的属性被所有实例共享
2.构造函数式继承
使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类(不使用原型)
function sonClass(name){
parentClass.call(this,name);
}
缺点:
- 方法都在构造函数中定义,每次创建实例都会创建一遍,无法实现复用
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
优点: 3. 避免了引用类型的属性被所有实例共享(创建子类实例时调用父类构造函数,每个实例都会将父类中的属性复制一份。) 4. 可以在 Child 中向 Parent 传参
例子:
function parentClass(age) {
this.names = ['tom', 'jack'];
this.age = age;
}
function sonClass(age) {
parentClass.call(this, age);
}
var child1 = new sonClass(18);
child1.names.push('mike');
console.log(child1.names,child1.age);// ["tom", "jack", "mike"] 18
var child2 = new sonClass(20);
console.log(child2.names,child2.age); //["tom", "jack"] 20
3.组合继承(常用)
原型链继承和构造函数式继承组合。 用原型链实现对原型属性和方法的继承,用借用构造函数技术来实现实例属性的继承。
function sonClass(name,age){
parentClass.call(this,name); // 第二次调用parentClass()
this.age = age;
}
sonClass.prototype = new parentClass();//第一次调用parentClass()
sonClass.prototype.constructor = sonClass;// 重写sonClass.prototype的constructor属性,指向自己的构造函数sonClass
优点:融合原型链继承和构造函数式继承的优点,是 JavaScript 中最常用的继承模式。
缺点:父类的构造函数执行了两遍:一次在子类的构造函数中call方法执行一遍,一次在子类原型实例化父类的时候执行一遍。
4.原型式继承
就是 ES5 Object.create 的模拟实现,将传入的对象作为创建的对象的原型。
function createObj(o){
function F(){}
F.prototype = o;
return new F();
}
var son = createObj(parent);
缺点:
- 和原型链继承一样,父类对象的引用类型值被共用。
- 无法传递参数
5.寄生式继承
在原型式继承的基础上,增强对象,返回构造函数 主要作用是为构造函数新增属性和方法,以增强函数
function createObj (o) {
var clone = Object.create(o);
clone.sayName = function () {
console.log('hi');
}
return clone;
}
缺点(同原型式继承):
- 父类对象的引用类型值被共用。
- 无法传递参数
6.寄生组合式继承
结合借用构造函数传递参数和寄生模式实现继承
function inheritObject(o){
function F(){};
F.prototype = o;
return new F();
}
function inheritPrototype(sonClass,parentClass){
var p = inheritObject(parentClass.prototype);// 创建对象,创建父类原型的一个副本
p.constructor = sonClass; // 增强对象,弥补因重写原型而失去的默认的constructor 属性
sonClass.prototype = p;// 指定对象,将新创建的对象赋值给子类的原型
}
// 借用构造函数传递增强子类实例属性(支持传参和避免篡改)
function sonClass(name,age){
parentClass.call(this,name);
this.age = age;
}
inheritPrototype(sonClass,parentClass);
这是最成熟的方法,也是现在库实现的方法。
7.Object.assign
Object.assign会把 Parent原型上的函数拷贝到 Child原型上,使 Child的所有实例都可用 Parent的方法。它将返回目标对象,如果有重复的属性会被覆盖。
Object.assign(Child.prototype,Parent.prototype);
Child.prototype.constructor = Child;
8. ES6类Extends
使用extends表明继承自哪个父类,并且在子类构造函数中必须使用super,可以看作是 Parent.call(this,value);
class Child extends parentClass{
constructor(value){
super(value);
this.val = value;
}
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!