资讯专栏INFORMATION COLUMN

[原创] JavaScript中的继承总结

sixgo / 3018人阅读

摘要:中继承比较复杂,坑比较多,最近有点时间整理下,记录下来。的继承实现方式大概分类如下的两大类,每一种实现都有自己的有点和缺点,根据场景选择吧通过修改原型链来来实现继承通过复制父类来来实现继承为了理解继承的原型链的变化,我画了原型链图。

JS 中继承比较复杂,坑比较多,最近有点时间整理下,记录下来。

JS 的继承实现方式大概分类如下的两大类,每一种实现都有自己的有点和缺点,根据场景选择吧

通过修改原型链来来实现继承

通过复制父类来来实现继承

为了理解继承的原型链的变化,我画了原型链图。下图是没有继承的时候,父类和子类的原型链图

function Parent(name, age) {
    this.name = name;
    this.age = age;
}
Parent.prototype.getName = function () {
    return this.name;
};
Parent.prototype.getAge = function () {
    return this.age;
};
Parent.prototype.love = {
    game: ["DoTa"]
};

Parent.pay = function(){
  return 1000;
};

function Son(){}
修改原型链来来实现继承

修改原型链也有好几种,现在分开来说:

第一种

实现原理:修改原型链(子类的原型指向父类的原型)实现继承

优点:简单

缺点:子类修改影响父类

原型链图注意里面的红线

不调用构造方法实现

function Son(){}
Son.prototype = new Parent();
Son.prototype.constructor = Son;

调用构造方法实现

function Son(){
    Parent.apply(this, arguments)
}
Son.prototype = Parent.prototype;
Son.prototype.constructor = Son;

详细代码实现:https://github.com/xuanxiao2013/f2e-practice/blob/master/javascript-inherit/inherit1.js

第二种

实现原理:修改原型链(通过加入临时函数,阻止子类修改父类)实现继承

优点:子类即能继承父类,又基本不影响父类,达到真正意义上的继承

缺点:实例的对象和父类原型的对象相同的时候(父类的love),可能会出现子类修改父类对象原型中的所有属性被实例共享,共享很适合函数,对基本值的属性也可以(实例上添加同名属性),但是对引用类型的值的属性来说,就会有问题

原型链图注意里面的红线

ES3 实现方式详细代码实现:

function create(proto){
    var F = function(){};
    F.prototype = proto;
    return new F();
}

function Son(){
    Parent.apply(this, arguments);
}
Son.prototype = create(Parent.prototype);
Son.prototype.constructor = Son;

ES5 实现方式详细代码实现:

function Son(){
    Parent.apply(this, arguments);
 }
 Son.prototype = Object.create(Parent.prototype)
 Son.prototype.constructor = Son;

ES6 实现方式 详细代码实现:

class Parent{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
}
Parent.prototype.getName = function () {
    return this.name;
};
Parent.prototype.getAge = function () {
    return this.age;
};
Parent.prototype.love = {
    game: ["DoTa"]
};

class Son extends Parent {
    constructor(...args){
        super(...args);
    }
}

都说ES6 的Class 只是个语法糖,看来原因在这了

测试:

var parent = new Parent("jack", 40);
log("parentName:" + parent.getName()); // parentName:jack
var son = new Son("tom", 20);
Son.prototype.getName = function(){
    return this.name + " has good father";
};
log("sonName:" + son.getName()); // sonName:tom has good father
log("parentName:" + parent.getName()); // parentName:jack


log(Son.prototype.constructor === Son); // true
log(son instanceof Son); // true
log(son instanceof Parent); // true
log(son instanceof Object); // true


log("parent love:" + parent.love.game); // parent love:DoTa
log("son love:" + son.love.game); // son love:DoTa

log("------------------------");

// 注意这里
son.love.game = "DoTa2";
log("parent love:" + parent.love.game); // parent love:DoTa2
log("son love:" + son.love.game); // son love:DoTa2

log("------------------------");
son.love = {
    game: "DoTa3"
};
// 注意这里
log("parent love:" + parent.love.game); // parent love:DoTa2
log("son love:" + son.love.game); // son love:DoTa3
复制父类来来实现继承

实现原理:通过深度复制把父类的方法复制一份给子类来实现继承

优点:子类即能继承父类,又不影响父类,达到真正意义上的继承

缺点:复杂

详细代码实现:https://github.com/xuanxiao2013/f2e-practice/blob/master/javascript-inherit/inherit3.js

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86216.html

相关文章

  • 原理解释 - 收藏集 - 掘金

    摘要:巧前端基础进阶全方位解读前端掘金我们在学习的过程中,由于对一些概念理解得不是很清楚,但是又想要通过一些方式把它记下来,于是就很容易草率的给这些概念定下一些方便自己记忆的有偏差的结论。 计算机程序的思维逻辑 (83) - 并发总结 - 掘金从65节到82节,我们用了18篇文章讨论并发,本节进行简要总结。 多线程开发有两个核心问题,一个是竞争,另一个是协作。竞争会出现线程安全问题,所以,本...

    AlphaGooo 评论0 收藏0
  • 原理解释 - 收藏集 - 掘金

    摘要:巧前端基础进阶全方位解读前端掘金我们在学习的过程中,由于对一些概念理解得不是很清楚,但是又想要通过一些方式把它记下来,于是就很容易草率的给这些概念定下一些方便自己记忆的有偏差的结论。 计算机程序的思维逻辑 (83) - 并发总结 - 掘金从65节到82节,我们用了18篇文章讨论并发,本节进行简要总结。 多线程开发有两个核心问题,一个是竞争,另一个是协作。竞争会出现线程安全问题,所以,本...

    forrest23 评论0 收藏0
  • 傻傻分不清的__proto__与prototype

    摘要:今天同事小英童鞋问了我一个问题小英童鞋认为的原型对象是,所以会继承的属性,调用相当于调用,但结果不是一个方法。构造函数创建对象实例函数有两个不同的内部方法和。如果不通过关键字调用函数,则执行函数,从而直接执行代码中的函数体。 今天同事小英童鞋问了我一个问题: function Foo(firstName, lastName){ this.firstName = firstNam...

    YancyYe 评论0 收藏0
  • 基础知识 - 收藏集 - 掘金

    摘要:本文是面向前端小白的,大手子可以跳过,写的不好之处多多分钟搞定常用基础知识前端掘金基础智商划重点在实际开发中,已经非常普及了。 JavaScript字符串所有API全解密 - 掘金关于 我的博客:louis blog SF专栏:路易斯前端深度课 原文链接:JavaScript字符串所有API全解密 本文近 6k 字,读完需 10 分钟。 字符串作为基本的信息交流的桥梁,几乎被所有的编程...

    wdzgege 评论0 收藏0
  • 深入理解JavaScript系列8:S.O.L.I.D五大原则之里氏替换原则

    摘要:前言本章我们要讲解的是五大原则语言实现的第篇,里氏替换原则。因此,违反了里氏替换原则。与行为有关,而不是继承到现在,我们讨论了和继承上下文在内的里氏替换原则,指示出的面向对象。 前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle )。英文原文:http://fre...

    susheng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<