通过clone()实现对象继承是如何工作的
How does this implementation of object inheritance through clone() work?
我正在阅读kangax关于ECMAScript 5仍然不允许对数组进行子类化的博客。在这里,他使用了一种不同于正常原型结构的子类化方法
BaseClass.prototype = new Superclass();
他正在做的是:
function clone(obj) {
function F() { }
F.prototype = obj;
return new F();
}
然后像这样设置继承:
function Child() { }
Child.prototype = clone(Parent.prototype);
有人能解释一下这种由两部分组成的继承方法吗?它比上面简单的一行方法有什么好处?
编辑:我从评论中了解到,现在有一个标准的Object.create()
,它基本上解决了与clone()
方法相同的目的,但clone()
的实现是如何工作的?
这是一个有趣的问题。Douglas Crockford将你给出的代码(克隆函数)称为"原型继承",并在他的网站上的这篇文章中进行了描述。这个模式变得流行起来,并在ECMA脚本5中被形式化为Object.create(),如果你看看对象创建的规范,它与Crockford函数的规范完全相同。它是这样使用的:
var Animal = {
species: "mammal",
noises: function () {
console.log("makes noises")
},
actions: ["roll back", "jump up"]
}
var Cat = Object.create(Animal);
Cat.name = "blacky"
Cat.miau = function () {
console.log("miau miau");
}
Crockford也调用这种差分继承,因为在定义子类的新属性时,只需指定子类和超类之间的差异。Cat现在有了自己的属性"name"和自己的方法"miau"。
我认为这方面的主要问题是,您仍然在实例之间共享引用值,例如数组。
如果我们这样做:
var Cat2 = Object.create(Animal);
Cat2.actions.push("bite Henry");
Cat2.actions
["roll back", "jump up", "bite Henry"]
Cat.actions
["roll back", "jump up", "bite Henry"]
但至少实例基元属性是不共享的,这很好。
Cat2.name
undefined
Cat.name
"blacky"
要演示为什么要使用Object.create或辅助函数来设置继承原型,请参阅以下代码:
function Hamster(name){
if(name === undefined){
throw new Exception("Name cannot be undefined");
}
this.name=name;
};
function RussionMini=function(name){
Hamster.apply(this,arguments);
};
RussionMini.prototype=new Hamster();//throws Error
您可以执行RussionMini.prototpe=new Hamster("dummyvalue");
,但如果需要传递一个在声明对象(如DOM元素)时不可用的值,该怎么办。您仍然可以传递一个伪代码,但它会使代码更加复杂,并且在重构时更容易破坏。
这两个例子都不能修复prototype.constructor,因此this.constructor
将指向错误的函数(当您使用Object.create(Parent.protype)时也会发生这种情况;`
关于继承、重写函数和使用构造函数的原型的更多信息,可以在这里找到:原型继承-编写
- Javascript:selenium Web驱动程序isDisplayed()不工作
- jQuery UI自动完成突然停止工作
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- JavaScript打印功能使日历停止工作
- Javascript.getHours()工作不正常
- 为什么这在IE中的工作方式与在Firefox中不同
- 视频HTML没有'无法在Internet Explorer 11上工作
- 扩展移相器按钮类不工作
- Firebase迁移-简单的Firebase.set没有'不再工作了——旧的还是新的
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- 正在尝试使用if和else添加类,但无法正常工作
- Jquery FadeIn FadeOut 只工作一次
- Foreach无法在Typescript中工作
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- 为什么不是't窗口.恢复正常工作吗?(javascript/jquery)
- JS可以在Chrome中工作,但不能在Firefox中工作
- ajaxToolkit PopupControlExtender不工作.过时的
- HTML标记在脚本标记中工作
- 在JavaScript中的类中,push和concat的工作方式有何不同