美文网首页我爱编程
js继承与实例化(个人整理)

js继承与实例化(个人整理)

作者: 博客专用马甲 | 来源:发表于2015-08-07 01:26 被阅读2310次

对于js继承一直都是半懂半不懂的状态,感觉需要整理一下:

参考自:
JavaScript原型继承工作原理
JavaScript实现继承的几种方式
JavaScript继承方式详解

1. 区分类继承和实例化的差别

非常常用的类继承是这个样子的:
B.prototype = new A()
这时候特别容易和实例化给混淆了(反正我混了):
b = new A()

感觉不好玩了对不对,这个时候开始好奇new到底干了什么事情(理解原理非常重要的撒):

创建类的示例 初始化 返回实例

用代码表示如下:

function New (f) { 
    var n = { '__proto__': f.prototype }; /*第一步*/ 
    return function () { 
        f.apply(n, arguments); /*第二步*/ 
        return n; /*第三步*/
     };
}

还是有点云里雾里,怎么区分什么时候是类继承,什么时候是实例化呢?
呐,首先我先想到一切皆为函数,所以无论是实例化还是继承,本质上都是拥有A的属性(函数或者值)嘛,所以必须要想清楚js是怎么查找一个东西的属性的哇:

当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。

用代码表示如下:

function getProperty(obj, prop) {
    if (obj.hasOwnProperty(prop)){
        return obj[prop]
    }else if (obj.__proto__ !== null){
        return getProperty(obj.__proto__, prop)
    }else{
        return undefined
    }
}

恩,这下子可以解释两者区别了:
B.prototype = new A() : B.prototype要找自己属性的时候:先看看自己有没有 --> 看看自己的proto(也就是A.prototype)有没有 --> 一路往上
b = new A(): b找自己属性的时候:先看看自己有没有 --> 看看自己的proto(也就是A.prototype)有没有 --> 一路往上

n年前收集了一张图,仔细看,就是我前面整理的内容了(不要晕,仔细看,此图博大精深):

原型链解释.jpg

对于原型链不理解的其实可以去看Typescript,对比Typescript和它生成出来的js代码,就容易理解了。

2. js继承方式

理解第一节以后,js继承方式什么的,so easy啦~

心中只要记住,作为子类的我,只要能够拥有父类prototype里的属性,就可以算作继承了(个人理解,觉不对可举正)

感觉可以用生孩子的例子贯穿这一节嘛~

  • 原型链继承(其实就是最开始1的那种继承)

    //父类
    var Animal = function(){
      //可以在构造函数里面直接设置属性~
      this.name = 'animal';
    }
    //也可以通过prototype
    Animal.prototype.say = function(){
      console.log('Animal here');
    }
    
    //子类
    var Dog = function(){
    
    }
    Dog.prototype = new Animal();
    //改写父类prototype
    Dog.prototype.name = 'dog';
    
    //创建实例
    var doge = new Dog();
    console.log(doge.name)  //'dog';
    doge.say()  //'Animal here';
    

    最传统的办法了,自己生

  • 构造继承(借用方法)

    //父类还是一样样的
    var Dog = function(){
        Animal.call(this);
        this.name = 'dog';
    }
    
    //创建实例
    var doge = new Dog();
    console.log(doge.name) //'dog';
    doge.say() //error;
    

咦,哪里不对,怎么会error说没有这个方法?!!
仔细看代码,要理解,Dog只是借用了Animal的构造方法,Animal的say方法是在prototype上的,当然找不到了,所以这种方法的问题就很明显啦,就是并没有依靠原型链关系,就像试管婴儿嘛,我只是借个肚子生小孩而已,基因还是我的(哈哈哈) 也就是说如果通过instanceof检查doge和Animal的关系,会发现返回没有关系的呦。

  • 实例继承
    var Dog = function(){
    var dog = new Animal();
    dog.name = 'dog';
    return dog;
    }

    //创建实例
    var doge = new Dog();
    console.log(doge.name)  //'dog';
    doge.say()  //'Animal here';
    console.log(doge instanceof Animal)  // true
    console.log(doge instanceof Dog)  // false
    

额,就好象小明爸爸借隔壁老王过来生小明~~ 实例是父类的实例,而不是子类的实例。

  • 拷贝继承(暴力继承)
    var Dog = function(){
    var animal = new Animal();
    for(var attr in animal){
    this[attr] = animal[attr];
    }
    this.name = 'dog';
    }

    //创建实例
    var doge = new Dog();
    console.log(doge.name) //'dog';
    doge.say() //'Animal here';
    console.log(doge instanceof Animal) // false
    console.log(doge instanceof Dog) // true
    

最野蛮的办法:把老王家的儿子抓过来,照着他的样子自己生一个

  • 组合继承
    var Dog = function(){
    Animal.call(this, arguments);
    this.name = 'dog';
    }
    Dog.prototype = new Animal();

    //创建实例
    var doge = new Dog();
    console.log(doge.name) //'dog';
    doge.say() //'Animal here';
    console.log(doge instanceof Dog) // true
    console.log(doge instanceof Animal) // true

相当于借A肚子生孩子,完事拉住孩子和A的手说:我是你爸,你也来自A。好处是解决了实例继承的问题,坏处嘛,就是叫了两遍A。

  • Object.create(proto[, propertiesObject])
    ES5引入,我看着underscore用的主要也是这个办法。
    代码原理解释:
    Object.create = function (parent) {
    function F() {}
    F.prototype = parent;
    return new F();
    };
    不多解释了,至于怎么生,这个我真编不出来了,有点像建个工厂,要生娃的基因给我,出来就是你娃。

其实说多了,个人觉得重在理解,目标是生娃,至于怎么生,就要看清好处坏处了。

3. 关于创建对象模式的一点嗑叨

什么是创建对象模式?(看到模式就犯头疼)额,说人话就是实例化,常见的就是var a = new A()
以前还小的时候看各种模式什么的,晕头转向,浪费时间也浪费脑力。
所以推荐先实践(酒肉穿肠过,佛祖心中流)实践多了,就会发现模式不模式,自己平时就在用。
//其实就是好累好累的,下次再补了

---------此处为捡节操分割线----------
最近面试发现自己表达能力很不行,不知道写出来的博客会不会也整晕别人了== 欢迎举正~

相关文章

  • js继承与实例化(个人整理)

    对于js继承一直都是半懂半不懂的状态,感觉需要整理一下: 参考自:JavaScript原型继承工作原理JavaSc...

  • js面向对象总结

    1、类与实例 类的声明 实例化 2、类与继承 继承的几种方式

  • js一些技巧.md

    js中的constructor和prototype 组合继承与寄生继承 组合继承 可以继承实例属性和方法,也可以继...

  • JS面向对象

    类与实例 创建类 实例化 类与继承 实现继承的几种方式 方式一:利用构造函数进行继承 但是这种方法缺点是无法继承父...

  • Vue2学习笔记:vue实例

    一、实例化vue 二、添加实例化选项 三、扩展vue构造器 四、属性与方法 五、vue实例选项与原生js的关系 六...

  • JavaScript原型链

    js中的继承是基于原型链来实现的,被实例化对象的__proto__属性指向了继承的对象 这段代码中,foo_a._...

  • JavaScript继承

    js继承方式js是一门弱类型动态语言,封装和继承是他的两大特性 原型链继承 优点: 简单易于实现 实例是子类的实例...

  • 面向对象编程

    主要包括: 基本概念 属性私有化(类的封装) 实例属性与类属性 静态方法、类方法、与实例方法 继承与多态 获取对象...

  • JS继承的方法

    JS继承的方法有六种: 1、原型链继承 2、构造继承 3、实例继承 4、拷贝继承 5、组合继承 6、寄生组合继承

  • php之trait假类

    类都知道,可以继承跟被继承,可以被实例化得到一个对象 但trait假类不能被实例化,只在继承方面有个贡献,这个贡献...

网友评论

    本文标题:js继承与实例化(个人整理)

    本文链接:https://www.haomeiwen.com/subject/rblbqttx.html