js(原型)继承
author:一佰互联 2019-03-29   click:187

简介:我们已经看过了许多 JavaScript 程序中常用的模拟类行为的方法,但是如果没有“继承” 机制的话,JavaScript 中的类就只是一个空架子。 实际上,我们已经了解了通常被称作原型继承的机制,a 可以“继承”Foo.prototy ...

我们已经看过了许多 JavaScript 程序中常用的模拟类行为的方法,但是如果没有“继承” 机制的话,JavaScript 中的类就只是一个空架子。 实际上,我们已经了解了通常被称作原型继承的机制,a 可以“继承”Foo.prototype 并访 问 Foo.prototype 的 myName() 函数。但是之前我们只把继承看作是类和类之间的关系,并 没有把它看作是类和实例之间的关系:

js(原型)继承

这张图不仅展示出对象(实例)a1 到 Foo.prototype 的委托关系,还展示出 Bar.prototype 到 Foo.prototype 的委托关系,而后者和类继承很相似,只有箭头的方向不 同。图中由下到上的箭头表明这是委托关联,不是复制操作。

js(原型)继承

这段代码的核心部分就是语句 Bar.prototype = Object.create( Foo.prototype )。调用 Object.create(..) 会凭空创建一个“新”对象并把新对象内部的 [[Prototype]] 关联到你 指定的对象(本例中是 Foo.prototype)。 换句话说,这条语句的意思是:“创建一个新的 Bar.prototype 对象并把它关联到 Foo. prototype”。 声明 function Bar() { .. } 时,和其他函数一样,Bar 会有一个 .prototype 关联到默认的 对象,但是这个对象并不是我们想要的 Foo.prototype。因此我们创建了一个新对象并把它关联到我们希望的对象上,直接把原始的关联对象抛弃掉。注意,下面这两种方式是常见的错误做法,实际上它们都存在一些问题:// 和你想要的机制不一样! Bar.prototype = Foo.prototype; // 基本上满足你的需求,但是可能会产生一些副作用 :( Bar.prototype = new Foo(); Bar.prototype = Foo.prototype 并不会创建一个关联到 Bar.prototype 的新对象,它只 是让 Bar.prototype 直接引用 Foo.prototype 对象。因此当你执行类似 Bar.prototype. myLabel = ... 的赋值语句时会直接修改 Foo.prototype 对象本身。显然这不是你想要的结 果,否则你根本不需要 Bar 对象,直接使用 Foo 就可以了,这样代码也会更简单一些。Bar.prototype = new Foo() 的确会创建一个关联到 Bar.prototype 的新对象。但是它使用 了 Foo(..) 的“构造函数调用”,如果函数 Foo 有一些副作用(比如写日志、修改状态、注 册到其他对象、给 this 添加数据属性,等等)的话,就会影响到 Bar() 的“后代”,后果 不堪设想。 因此,要创建一个合适的关联对象,我们必须使用 Object.create(..) 而不是使用具有副 作用的 Foo(..)。这样做唯一的缺点就是需要创建一个新对象然后把旧对象抛弃掉,不能 直接修改已有的默认对象。 如果能有一个标准并且可靠的方法来修改对象的 [[Prototype]] 关联就好了。在 ES6 之前, 我们只能通过设置 .__proto__ 属性来实现,但是这个方法并不是标准并且无法兼容所有浏 览器。ES6 添加了辅助函数 Object.setPrototypeOf(..),可以用标准并且可靠的方法来修 改关联。 我们来对比一下两种把 Bar.prototype 关联到 Foo.prototype 的方法: // ES6 之前需要抛弃默认的 Bar.prototype Bar.ptototype = Object.create( Foo.prototype ); // ES6 开始可以直接修改现有的 Bar.prototype Object.setPrototypeOf( Bar.prototype, Foo.prototype ); 如果忽略掉 Object.create(..) 方法带来的轻微性能损失(抛弃的对象需要进行垃圾回 收),它实际上比 ES6 及其之后的方法更短而且可读性更高。不过无论如何,这是两种完 全不同的语法。本文仅代表作者个人观点,不代表巅云官方发声,对观点有疑义请先联系作者本人进行修改,若内容非法请联系平台管理员,邮箱2522407257@qq.com。更多相关资讯,请到巅云www.yx10011.com学习互联网营销技术请到巅云建站www.yx10011.com。