摘要:组合方式实现继承原型链构造函数喵喵喵汪汪汪与的唯一区别是多了这一句组合方式实现了对构造函数内和原型上所有属性和方法的继承,并且的实例对象之间也不会相互干扰。
前言
关于JavaScript继承相关的定义和方法网上已经有很多解释啦,本菜鸟就不抄抄写写惹人嫌了,本文主要探讨三种基本的继承方式并且给出优化方案。
正文
借助构造函数实现继承
function Parent1() {
this.name = "喵喵喵"; this.arr = [1]; } Parent1.prototype.say = function () { alert("我肯定没被继承,所以弹不出来"); }; function Child1() { Parent1.call(this); // 这里是借助构造函数实现继承的关键 } var t1 = new Child1();
好的,我们来通过控制台看看结果:
可以发现,Child1已经成功继承了Parent1构造函数中个属性,那么问题来了,Parent1原型的属性Child1继承了吗?
答案是并没有!这就是借助构造函数实现继承的缺点,被继承对象原型上的属性不能被继承。
2.借助原型链实现继承
Tips:所有实例对象共享的属性和方法都放在prototype中
function Parent2() { this.arr = [1]; this.a = "1"; } Parent2.prototype.say = function () { alert("终于被继承了"); }; function Child2() { this.type = "汪汪汪"; } Child2.prototype = new Parent2(); // 这里是借助原型链实现继承的关键 var s1 = new Child2(); var s2 = new Child2();
我们再次打开控制台看看:
ok!到这里,我们已经成功实现让Parent2中的属性以及它原型链上的属性都被继承。但是这里要注意包含引用类型属性的原型会被所有的实例共享。啥意思呢?Child2.prototype = new Parent2(); 这行代码把Parent2的实例赋给了Child2的原型,而Parent2中存在引用类型this.arr。
s1和s2本是Child2的两个不同实例,但修改s2.arr同样映射到s1.arr这个问题体现出了借助原型链实现继承的缺点: Parent2中的引用属性被Child2的实例共享了。
3.组合方式实现继承(原型链 + 构造函数)
function Parent3() { this.type = "喵喵喵"; this.arr = [1] } function Child3() { this.type = "汪汪汪"; Parent3.call(this); // 与2的唯一区别是多了这一句 } Child3.prototype = new Parent3(); var s3 = new Child3(); var s4 = new Child3();
组合方式实现了Child3对Parent3构造函数内和原型上所有属性和方法的继承,并且Child3的实例对象之间也不会相互干扰。当然啦,厉害的看官已经发现了组合方式的问题:Parent3.call(this)、new Parent3();
在实现组合继承的过程中Parent3执行了两次,这其实是没有必要的。
组合方式实现继承-优化
function Parent4() { this.type = "喵喵喵"; this.arr = [1] } Parent4.prototype.cide = [1,2,3]; function Child4() { this.type = "汪汪汪"; Parent4.call(this); } Child4.prototype = Parent4.prototype;// 优化重点 var s5 = new Child4(); var s6 = new Child4();
这种组合方式的优化方案其实可以分两步来看:
1) Parent4.call(this) 实现对构造函数中的属性和方法的继承
2)Child4.prototype = Parent4.prototype; 实现对构造函数的原型的属性和方法的继承
观察3中的代码我们可以发现,通过Parent3.call(this)我们规避了Parent构造函数中引用属性对child实例的影响,但如果Parent的原型中存在引用类型(Parent4.prototype.cide),那么在child的实例中修改该属性,同样会映射到其它实例。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/88903.html
摘要:构造函数通过原型继承了构造函数和原型,这就形成了一个链条,通俗的讲就是原型链继承。而且方法只能冒充构造函数里面的属性和方法而无法冒充原型对象里面的属性和方法还有最大的问题就是重复使用。 前言: 写到这里,差不多就把OOP完结了,写了几篇OOP的文章,但是只是略懂皮毛,可能深入的OOP还有很多,但是我感觉写到这里也算是差不多完结了。 继承 继承是面向对象比较核心的概念,其他语言可能实现...
摘要:面向对象面向对象编程的全称是,简称,面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。面向对象编程的三个主要特征是封装继承多态。 面向对象 面向对象编程的全称是Object Oriented Programming,简称OOP,面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。面向对象编程可以看做是使用一系列对象相互协作的软件设计,面向对象程序设计的目的是在编程中促...
摘要:注意这里跟原型链继承有个比较明显的区别是并没有使用继承而是在子类里面执行父类的构造函数相当于把父类的代码复制到子类里面执行一遍这样做的另一个好处就是可以给父类传参。 Javascript继承 学过后端语言的同学对继承并不陌生,但是对JS继承少许还是有些困惑,不要试图问我是如果知道的,其实javascript继承主要是基于原型prototype实现的。 其实当你真正了解了原型链时候,再看...
摘要:在这其中我们就逃不开要讨论继承原型对象构造函数实例了。想要获得某一类型的构造函数可以用来获得,也可以对该属性进行赋值操作。三上面就提到一点是指构造函数的原型对象,它是一个对象,它是构造函数的属性。 原型链这一个话题,需要和很多概念一起讲,才能串成一个比较系统的知识点。在这其中我们就逃不开要讨论继承、原型对象、构造函数、实例了。 一、构造函数 构造函数是一类特殊的函数,它的作用是用来生成...
摘要:中的和是一门很灵活的语言,尤其是。即然是面向对象的编程语言,那也是不可或缺的。在中,永远指向的是他的调用者。定义是存在于实例化后对象的一个属性,并且指向原对象的属性。我们在扩展的时候,同时父类也会有对应的方法,这很显然是一个很严重的问题。 javascript中的this和new javascript是一门很灵活的语言,尤其是function。他即可以以面向过程的方式来用,比如: f...
阅读 2353·2021-11-12 10:34
阅读 1449·2019-08-29 16:15
阅读 2657·2019-08-29 15:17
阅读 1303·2019-08-23 17:09
阅读 374·2019-08-23 11:37
阅读 2430·2019-08-23 10:39
阅读 449·2019-08-22 16:43
阅读 3090·2019-08-22 14:53