细说js继承

为了解决包含引用类型值的原型属性会被所有实例共享的问题,大神们发明了在子类型构造函数的内部调用超类型构造函数然后通过apply()和call()方法在(将来)新创建的对象上执行构造函数的方式来实现继承,如下

function SuperType() {    this.colors = ["red", "blue", "green"];}function SubType() {//调用SuperType 并且通过call()方法修正this指向  SuperType.call(this); }var instance1 = new SubType();instance1.colors.push("black");//"red,blue,green,black"alert(instance1.colors);//"red,blue,green"var instance2 = new SubType();alert(instance2.colors);

登录后复制

以上例子中在SubType()调用了SuperType()构造函数。通过使用call()方法(或apply()方法也可以),我们实际上是在(未来将要)新创建的SubType实例的环境下调用了SuperType构造函数。这样一来,就会在新SubType对象上执行SuperType()函数中定义的所有对象初始化代码。结果,SubType的每个实例就都会具有自己的colors属性的副本了(互不影响)。

使用这种方式继承的好处:

可以在子类型构造函数中向超类型构造函数传递参数。如下

function SuperType(name) {  this.name = name;}function SubType() {//继承了SuperType,同时还传递了参数SuperType.call(this, "Nicholas");    //实例属性    this.age = 29;}var instance = new SubType();  //"Nicholas";alert(instance.name);//29alert(instance.age);

登录后复制

SuperType只接受一个参数name,该参数会直接赋给一个属性。在SubType构造函数内部调用SuperType构造函数时,实际上是为SubType的实例设置了name属性。为了确保SuperType构造函数不会重写子类型的属性,可以在调用超类型构造函数后,再添加应该在子类型中定义的属性。

使用这种方式继承的坏处:

1.方法都在构造函数中定义
 2.在超类型的原型中定义的方法,对子类型而言也是不可见的 如下

function SuperType(name) {  this.name = name;}SuperType.prototype.a=function(){    alert("aaaa");}function SubType() {//继承了SuperType,同时还传递了参数SuperType.call(this, "Nicholas");    //实例属性 this.age = 29;}var instance = new SubType();console.log(instance);

登录后复制

细说js继承
我们在控制台可以看到子类型原型中无法获取超类型的a方法

二   组合继承

将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式,主要的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。下面来看一个例子

function SuperType(name) {  this.name = name;  this.colors = ["red", "blue", "green"];}SuperType.prototype.sayName = function() {  alert(this.name);};function SubType(name, age) { //继承name属性    SuperType.call(this, name);    this.age = age;}//继承方法 (拼接原型链)SubType.prototype = new SuperType();SubType.prototype.sayAge = function() {  alert(this.age);};var instance1 = new SubType("Nicholas", 29);instance1.colors.push("black"); //"red,blue,green,black"alert(instance1.colors);//"Nicholas";instance1.sayName();//29instance1.sayAge();var instance2 = new SubType("Greg", 27);//"red,blue,green"alert(instance2.colors);//"27"; instance2.sayAge();//"Greg"; instance2.sayName();

登录后复制

细说js继承
我们看到现在实例可以访问的超类型的原型上的方法了
SuperType构造函数定义了两个属性:name和colors。SuperType的原型定义了一个方法sayName()。Sub-Type构造函数在调用SuperType构造函数时传入了name参数,紧接着又定义了它自己的属性age。然后,将SuperType的实例赋值给SubType的原型,然后又在该新原型上定义了方法sayAge()。这样一来,就可以让两个不同的SubType实例既分别拥有自己属性——包括colors属性,又可以使用相同的方法了这种方式是目前js实现继承使用的最常见的方式

使用这种继承方式的不足

SubType.prototype = new SuperType()的确会创建一个关联到SubType.prototype 的新对象。但是它使用了SubType(..)的“构造函数调用”,如果函数SubType有一些副作用(比如写日志、修改状态、注册到其他对象、给this添加数据属性,等等)的话,就会影响到SubType()的“后代”。

改进方法

function SuperType(name) {  this.name = name;  this.colors = ["red", "blue", "green"];}SuperType.prototype.sayName = function() {  alert(this.name);};function SubType(name, age) {   //继承name属性      SuperType.call(this, name);      this.age = age;}//使用Object.create 生成对象来代替new SuperType()生成的对象SubType.prototype = Object.create(SuperType.prototype);SubType.prototype.sayAge = function() {  alert(this.age);};var instance1 = new SubType("Nicholas", 29);console.log(instance1 );

登录后复制

细说js继承
这样可以避免对SubType后代的影响

// ES6之前需要抛弃默认的SubType.prototypeSubType.ptototype = Object.create( SuperType.prototype );// ES6开始可以直接修改现有的SubType.prototypeObject.setPrototypeOf( SubType.prototype, SuperType.prototype );

登录后复制

相关推荐:

js继承 Base类的源码解析_js面向对象

JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现_javascript技巧

JS继承–原型链继承和类式继承_基础知识

以上就是细说js继承的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2789113.html

(0)
上一篇 2025年3月8日 18:38:35
下一篇 2025年2月23日 13:55:43

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • js单张图片平移切换效果实例分享

    本文主要为大家详细介绍了js实现单张图片平移切换效果,一张图移动到左边以后,从底部移回最右,等待下一次循环,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家。 本文参考了JQuery实现图片切换(自动切换+手动切换) 由于…

    编程技术 2025年3月8日
    000
  • JavaScript中运算符规则和隐式类型转换示例详解

    javascript中运算符规则的隐式类型转换是什么? 这是每个学习javascript的新手们都应该知道的一个问题,下面这篇文章主要给大家介绍了关于javascript中运算符规则和隐式类型转换的相关资料,需要的朋友可以参考借鉴,下面来一…

    编程技术 2025年3月8日
    200
  • js防刷新的倒计时代码 js倒计时代码

    这篇文章主要为大家详细介绍了js防刷新的倒计时代码,js倒计时的实现代码,具有一定的参考价值,对js感兴趣的小伙伴们可以参考一下本篇文章 最近在维护考试系统,在进行考试测试时无意中点击了刷新按钮,但是上面的倒计时并没有受到影响,同时在几篇博…

    编程技术 2025年3月8日
    200
  • Scala解析Json字符串实例详解

    本文主要介绍了 scala解析json字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家学习理解这部分内容,需要的朋友可以参考下,希望能帮助到大家、 Scala解析Json字符串的实例详解 1. 添加相应依赖        Jso…

    编程技术 2025年3月8日
    200
  • JavaScript使用FileReader实现图片上传预览效果

    这篇文章主要为大家详细介绍了javascript使用filereader实现图片上传预览效果,具有一定的参考学习javascript的价值,对javascript感兴趣的小伙伴们可以参考一下本篇文章 FileReader是HTML5 Fil…

    编程技术 2025年3月8日
    200
  • JS随机排序数组实例分析

    本文主要介绍了js随机排序数组实现方法,结合具体实例形式对比分析了javascript针对数组进行随机排序的相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。 做随机显示推荐广告的时候,需要随机排序数据数组,就动手写了一个,如下: fu…

    编程技术 2025年3月8日
    200
  • VUE.JS移动端框架Mint UI的使用方法详解

    本文主要介绍了基于vue.js的移动端框架mint ui的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 Mint UI GitHub:github.com/ElemeFE/mint 项…

    2025年3月8日
    200
  • node.js操作MongoDB实例分享

    本文主要介绍了node.js操作mongodb的实例详解的相关资料,希望通过本能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下,希望能帮助到大家。 node.js操作MongoDB时,需要安装mongodb包 1、使用npm安装…

    2025年3月8日 编程技术
    200
  • AngularJS中下拉框的高级用法实例讲解

    本文主要介绍了angularjs中下拉框的高级用法,结合实例形式分析了angularjs下拉框的遍历、选择、绑定、显示等功能实现方法,需要的朋友可以参考下,希望能帮助到大家。 HTML正文: {{sites}}选择的网址:{{site}}选…

    2025年3月8日
    200
  • Vue.js异步更新DOM策略及nextTick实例详解

    本文主要介绍了从vue.js源码看异步更新dom策略及nexttick,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助大家更好理解vue.js异步。 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论