手机版

重新理解JavaScript的六种继承方法

时间:2021-09-05 来源:互联网 编辑:宝哥软件园 浏览:

类继承(构造函数)

JS中没有类的概念,所谓的类也是模拟的。尤其是当我们使用新的关键字时,“类”的概念更像是其他语言中的类。类继承是调用函数对象中父类的构造函数,从而获取父类的方法和属性。调用和应用方法为类继承提供支持。通过改变它的工作环境,子类本身具有父类的各种属性。

var父亲=function(){ this . age=52;this . say=function(){ alert(' hello我是' this.name '而我是' this . age ' age ' age ');} } var child=function(){ this . name=' bill ';父亲打电话给(这个);} var man=new child();man . say();原型继承

原型继承常用于开发。它不同于类继承,因为继承不是在对象本身上,而是在对象的原型上。每个对象都有一个原型,它体现在浏览器中隐藏的__proto__属性中。您可以在一些现代浏览器中更改它们。例如,在zepto中,通过将zepto的fn对象添加到空数组的__proto__属性中,该数组就变成了zepto对象,并且拥有所有的方法。另一方面,当一个对象需要调用一个方法时,它会返回到最近的原型来找到该方法。如果它没有找到,它会继续往下看。通过一步一步的寻找,我们总能找到我们要找的方法。这些搜索到的原型形成了对象的原型链。原型最终指向null。原型继承的意思是把父对象的方法给子类的原型。这些方法和属性不属于子类的构造函数。

var父=function () {}父. prototype . a=function(){ } varchild=function(){ }//开始继承child.prototype=new父();var man=new child();man . a();可以看到第七行实现了原型继承。很多人都熟悉这种方式。通过在浏览器中打印man,我们可以看到每个原型的继承关系。

您可以看到子对象(由父亲实例化的对象)-父亲的逐步关系。Child通过中间层继承了父亲的原型。但是为什么中间有一层物体呢?为什么不把孩子。原型=父亲。原型?答案是这样做,孩子和父亲就没有区别了。您应该记得原型中有一个构造函数属性,它指向构造函数。按照正常情况,我们需要把构造函数的值改回指向子的构造函数。但是如果父. prototype直接赋给子. prototype,构造函数应该指向谁呢?因此,很明显,只有通过中间层,孩子和父亲才能保持独立的对象。

类继承与原型继承的比较

构造函数(类)继承

首先,构造函数继承的方法会存在于父对象中,每个实例都会将funciton保存在内存中,这会带来性能问题。

其次,类继承是不可变的。不能重用,在运行时,不能修改或添加新的方法,这种方式是死方法。很少只是在实践中使用。

原型继承

优点:

原型链可以改变:原型链上的父类可以被替换和扩展

子类可以通过改变原型链接来修改。此外,类继承不支持多重继承,但是对于原型继承,您只需要编写extend来扩展对象。

但是,原型链继承也有两个问题。

首先,包含引用类型值的原型属性将被所有实例共享(可以理解为:执行sub 1 . arr . push(2);首先,搜索sub1的属性,然后搜索实例属性(在本例中,没有实例属性)。如果没有找到,就开始向上搜索原型链,得到sub1的原型对象。搜索后发现有arr属性。然后2被插入到arr的末尾,所以sub2.arr改变了。

其次,创建子类型的实例时,不能将参数传递给超类型的构造函数。(其实应该说,没有办法在不影响所有对象实例的情况下,将参数传递给超类型构造函数。)原型链在实践中很少使用。

函数Super(){ this . val=1;this . arr=[1];}函数Sub(){//.} sub . prototype=new Super();//core var Sub 1=new Sub();var Sub 2=new Sub();sub 1 . val=2;sub 1 . arr . push(2);alert(sub 1 . val);//2 alert(sub 2 . val);//1 alert(sub 1 . arr);//1,2 alert(sub 2 . arr);//1,2摘要:

当类继承被实例化时,父类可以传递参数,并且不能被重用(父类是不可变的,并且父类的内容将在每个实例中保存在内存中)

实例化原型继承时,父类不能传递参数,可以重用(原型链可以更改(父类可以替换和扩展),父类不会保存在内存中,而是沿着原型链搜索,但结果是原型属性将被所有实例共享(特别影响引用类型值))

组合继承(最常用)

组合继承是原型链与借用构造函数技术相结合的继承模式。

思路是用原型链继承原型属性和方法,借用构造函数继承实例属性。

函数SuperType(name){ this . name=name;this.numbers=[1,2,3];} SuperType . prototype . SayName=function(){ console . log(this . name);}function SubType(姓名、年龄){SuperType.call(this,姓名);this.age=年龄;} subtype . prototype=new SuperType();subtype . prototype . Sayage=function(){ console . log(this . age);}var instance1=new SubType('aaa ',21);instance 1 . numbers . push(666);console . log(instance 1 . numbers);instance 1 . SayName();instance 1 . SayAge();var instance2=new SubType('bbb ',22);console . log(instance 2 . numbers);instance 2 . SayName();instance 2 . SayAge();将所有实例函数放在原型对象上,并传递sub prototype=new Super();继承父类函数,实现函数复用。

保留借用构造函数的优势,通过super . call(this);继承父类的基本属性和引用属性传递参数;

优点和缺点

优点:

可转移参数函数可以重复使用。不存在引用属性共享问题(图纸)。

(有一点小瑕疵)子类原型上有一个额外的父类实例属性,因为父类构造函数被调用了两次,生成了两个副本,而子类实例上的一个屏蔽了子类原型上的一个。又是一次内存浪费,比刚才好,但确实是一个缺陷。

以上就是边肖介绍的JavaScript的六种继承方式。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

版权声明:重新理解JavaScript的六种继承方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。