定义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. codeforces:MEX Queries分析和实现

    首先说明一下MEX,设S是自然数集合N的一个子集,那么S的MEX则为min(N\S),即不包含于S的最小自然数. 题目大意是存在一个空集S,提供n组输入(n<10^5),每组输入对应下面的一个指 ...

  2. mysql常见错误/usr/local/mysql/bin/mysqld: [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.

    出现这种情况多数是找不到data目录,还有就是对data目录没有写入权限.

  3. Caffe 议事(二):从零开始搭建 ResNet 之 网络的搭建(上)

    3.搭建网络: 搭建网络之前,要确保之前编译 caffe 时已经 make pycaffe 了. 步骤1:导入 Caffe 我们首先在 ResNet 文件夹中建立一个 mydemo.py 的文件,本参 ...

  4. POJ 1739 Tony's Tour (DP)

    题意:从左下角到右下角有多少种走法. 析:特殊处理左下角和右下角即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000 ...

  5. iOS隐藏导航条1px的底部横线

    第二种方法:1)声明UIImageView变量,存储底部横线 @implementation MyViewController { UIImageView *navBarHairlineImageVi ...

  6. Sophus VS2010编译不支持?C++11语法的缘故。那有没有不带C++11特性的Sophus版本呢?

    Eigen:3.1 3.0 Ceres:No Sophus: Sophus支不支持Windows编译?官网写的是通过了Windows的编译的 linux, os x:  windows:  code ...

  7. ui-router 之 $state.go

    Ui-router 之 $state.go   $state.go(arg1,arg2,arg3),有三个参数:第一个参数是你需要跳转的完整路由:第二个参数是query,当然不需要query,直接写{ ...

  8. OpenGl中的Nurbs B样条曲面绘制

    NURBS 贝塞尔曲线的缺点是当我们增加很多控制点的时候,曲线变得不可控,其连续性会变差差.如果控制点很多(高阶曲线),当我们调整一个控制点的位置,对 整个曲线的影响是很大的.要获得更高级的控制,可以 ...

  9. Scala程序编译运行

    1.编译 Scala演示代码如下: <pre name="code" class="plain">/** * @author Administrat ...

  10. MySQL—练习

    前面学习了MySQL的语句的基本用法,这里就开始做一些MySQL练习,这套题目一共45题,属于比较简单的,初学先试着做这个. 参考链接:https://www.cnblogs.com/SJP666/p ...