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

对于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()
以前还小的时候看各种模式什么的,晕头转向,浪费时间也浪费脑力。
所以推荐先实践(酒肉穿肠过,佛祖心中流)实践多了,就会发现模式不模式,自己平时就在用。
//其实就是好累好累的,下次再补了

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,622评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,018评论 1 10
  • 一. 普通对象与函数对象JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Obje...
    80bb3ef13dea阅读 1,579评论 1 10
  • JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如下: // 定义一个动物类 function ...
    才気莮孒阅读 446评论 0 0
  • 一个人炒了盘红烧茄子,坐在客厅一连吃了两碗饭。吃完后洗碗刷锅、把衣服放进洗衣机。房间里传来了电脑里播放的...
    star荣阅读 300评论 0 0