定义Foo,Bar

其中,Bar继承Foo

a是Bar的实例,包含有Foo和Bar的函数和属性:

function Foo(name) {
this.name = name;
} Foo.prototype.myName = function() {
return this.name;
}; function Bar(name,label) {
Foo.call( this, name );
this.label = label;
} // here, we make a new `Bar.prototype`
// linked to `Foo.prototype`
Bar.prototype = Object.create( Foo.prototype ); //核心代码 // Beware! Now `Bar.prototype.constructor` is gone,
// and might need to be manually "fixed" if you're
// in the habit of relying on such properties! Bar.prototype.myLabel = function() {
return this.label;
}; var a = new Bar( "a", "obj a" ); a.myName(); // "a"
a.myLabel(); // "obj a"

其中核心代码为

Bar.prototype = Object.create( Foo.prototype );

我们把这行代码换为以下几种写法,仍可使输出不变,但内部实现则完全不同了。

1、Bar.prototype = Foo.prototype;

推荐指数:★

评价:执行Bar.prototype.myLabel = ...的赋值语句会直接修改Foo.prototype对象本身,还不如不要Bar只用Foo

//第1种
Bar.prototype = Foo.prototype; a; //输出如下
Bar {name: "a", label: "obj a"} a.__proto__; //输出如下
Object {myName: function, myLabel: function, constructor: function} a.__proto__.__proto__; //输出如下
Object {method: function, __defineGetter__: function, __defineSetter__: function, hasOwnProperty: function, __lookupGetter__: function…}

2、Bar.prototype = new Foo();

推荐指数:★

评价:Foo函数的内容有可能产生副作用,他的操作将直接影响Bar()的后代,后果不堪设想。如下面的undefined

//第2种
Bar.prototype = new Foo(); a; //输出如下
Bar {name: "a", label: "obj a"} a.__proto__; //输出如下
Foo {name: undefined, myLabel: function} a.__proto__.__proto__; //输出如下
Object {myName: function, constructor: function}

3、Object.setPrototypeOf(Bar.prototype,Foo.prototype);

推荐指数:★★★★★

评价:完美,Bar的构造函数没变

Bar.prototype.constructor
function Bar(name,label) {
Foo.call( this, name );
this.label = label;
}

//第3种
Object.setPrototypeOf(Bar.prototype,Foo.prototype); a; //输出如下
Bar {name: "a", label: "obj a"} a.__proto__; //输出如下
Foo {myLabel: function, constructor: function} a.__proto__.__proto__; //输出如下
Object {myName: function, constructor: function}

4、Bar.prototype = Object.create(Foo.prototype);

推荐指数:★★★★

评价: Bar.prototype本身的constructor丢失了,去原型找,导致

Bar.prototype.constructor
function Foo(name) {
this.name = name;
}

//原文
Bar.prototype = Object.create(Foo.prototype); a; //输出如下
Bar {name: "a", label: "obj a"} a.__proto__; //输出如下
Foo {myLabel: function} a.__proto__.__proto__; //输出如下
Object {myName: function, constructor: function}

JavaScript的几种(原型)继承的更多相关文章

  1. 谈谈JavaScript的2种主要继承方式

    今天给自己巩固一下js的继承知识,基础不好,有不对的地方,请尽量拍砖,越重越好. js继承方法最主要的是2种,一种是通过原型的方式,一种是通过借用call&apply的构造函数方式. 1.原型 ...

  2. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  3. [转]Javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...

  4. JavaScript原型继承工作原理

    原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...

  5. JS继承之原型继承

     许多OO语言都支持两种继承方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.如前所述,由于函数没有签名,在ECMAScript中无法实现接口继承.ECMAScript只支 ...

  6. JS原型继承和类式继承

    前言 一个多月前,卤煮读了一篇翻译过来的外国人写的技术博客.此君在博客中将js中的类(构造)继承和原型继承做了一些比较,并且得出了结论:建议诸位在开发是用原型继承.文中提到了各种原型继承的优点,详细的 ...

  7. javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承

    javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...

  8. 玩转JavaScript OOP[3]——彻底理解继承和原型链

    概述 上一篇我们介绍了通过构造函数和原型可以实现JavaScript中的“类”,由于构造函数和函数的原型都是对象,所以JavaScript的“类”本质上也是对象.这一篇我们将介绍JavaScript中 ...

  9. web前端学习(二) javascript对象和原型继承

    目录 1. JavaScrpt对象 2. 原型对象和继承 3. 对象的克隆 (1)javascript对象 在JS中,对象是属性的容器.对于单个对象来说,都由属性名和属性值构成:其中属性名需要是标识符 ...

  10. 理解JavaScript中的原型继承(2)

    两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...

随机推荐

  1. 使用Git将码云上的代码Clone至本地

    1. 安装Git https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git Git的网站上有详细的分各种系统的安 ...

  2. 2018,学会python 在新公司扎根

    五月份跳槽了,来新公司,是个跟我之前业务完全不同的行业,偏硬件,可是对硬件没有什么概念.而且自己都不知道从哪里下手的感觉.终于明白自己在上家公司已经将人待的生了锈,我们庆幸,也许还是不晚的. 执行学习 ...

  3. Shiro01 功能点框图、架构图、身份认证逻辑、身份认证代码实现

    基本功能点 功能点框图 功能点说明 1.Authentication:身份认证/登录,验证用户是不是拥有相应的身份: 2.Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个 ...

  4. java工具类 --千分位方法

    /** * 千分位方法 * @param text * @return */ public static String fmtMicrometer(String text) { DecimalForm ...

  5. 四元数--结合《real time rendering》中关于四元数部分

    四元数产生于1843年,是复数的一个扩展,所以里面包含了一些复数的运算.直到1985年才在图形学中使用. 四元数的优势是,相对与矩阵和欧拉角,四元数更直观和方便.四元数还可以用作某些方向上的插值,而欧 ...

  6. Luogu 4449 于神之怒加强版

    挺套路的题,然而一开始还是想错了…… $\sum_{i = 1}^{n}\sum_{j = 1}^{m}gcd(i, j) ^ {k} = \sum_{T = 1}^{min(n, m)}\left ...

  7. IndexedDB:浏览器里内置的数据库(转)

    出处;http://www.webhek.com/indexeddb/ IndexedDB是HTML5规范里新出现的浏览器里内置的数据库.对于在浏览器里存储数据,你可以使用cookies或local ...

  8. myeclispe2014启动后报错 Subclipse talks to Subversion via a Java API that requires access to native libraries.

    解决方案: Window -> Preferences -> Team -> SVN, 将SVN接口的Client修改为如图所示

  9. 前端福利之jQuery文字轮播特效(转)

    闲谈:离开学校那座象牙塔已经也有大半年的事件了,生活中不再充满了茫然只有忙碌.连续加班加点大半个月,做的活动项目终于算是告一段落了,而今天也将是考验其真正价值的时候,现在将这次开发中遇到的问题做一下总 ...

  10. Linux的磁盘分区(三)

    RAID 廉价冗余磁盘阵列 Redundant Arrays of Inexpensive Disks 不同级别的RAID功能.特性各不相同 对比项 RAID0 RAID1 RAID10 RAID5 ...