好吧代理凯,我会以不同于Esailija的方式来处理这个问题。我们从简单的对象开始。例如说,你已经有一个对象调用gandalf
:
var gandalf = {
color: "grey",
comeBack: function() {
this.color = "white";
return this;
}
};
有这个代码没有构造函数。因此这段代码很容易理解。我是对的还是对的?
好的,现在我要去做一些真棒。我会从gandalf
创建radagast
:
var radagast = Object.create(gandalf);
radagast.color = "brown";
这里发生了什么?让我们来打破它:
- 我们使用
Object.create
从gandalf
创建一个名为radagast
新对象。因此radagast
继承自gandalf
。
- 我们将
color
的radagast
设置为棕色而不是灰色。
为了使它更加简单想象一下你和我有以下的对话:
I: Hey Agent Kay, I met Radagast yesterday.
U: Who's Radagast?
I: Hmm... do you know who's Gandalf?
U: Yes, I do.
I: Well Radagast is just like Gandalf except that he's brown instead of white.
这正是继承在JavaScript中的工作原理。你看到JavaScript有原型继承。在原型继承中,对象从其他对象继承。在这种情况下,radagast
继承自gandalf
。
现在他们的方式原型继承通常在JavaScript中实现是很奇怪的。我称之为constructor pattern of prototypal inheritance。当您创建的Gandalf
一个实例并实例继承什么对象
function Gandalf() {
this.color = "grey";
}
Gandalf.prototype.comeBack = function() {
this.color = "white";
return this;
};
现在:例如,把你的代码?它从Gandalf.prototype
继承:
var gandalf = new Gandalf;
alert(Object.getPrototypeOf(gandalf) === Gandalf.prototype); // true
发生了什么事时,你说new Gandalf
是:
var gandalf = Object.create(Gandalf.prototype);
Gandalf.call(gandalf);
如果展开Gandalf.call(gandalf)
的你:
var gandalf = Object.create(Gandalf.prototype);
gandalf.color = "grey";
现在把你的第二个例子:
function Gandalf() {
this.color = "grey";
this.comeBack = function() {
this.color = "white";
return this;
};
}
在当你创建的Gandalf
一个实例这种情况下,你基本上这样做:
var gandalf = Object.create(Gandalf.prototype);
gandalf.color = "grey";
gandalf.comeBack = function() {
this.color = "white";
return this;
};
因此,你创建一个新的Gandalf
每次创建一个新的功能comeBack
。因此,如果您拨打new Gandalf
10次,您也将拥有10个不同的comeBack
功能。
与此相比,在第一个例子,因为comeBack
是在Gandalf.prototype
定义,我们每次打电话new Gandalf
时候我们得到一个新的对象,从Gandalf.prototype
继承。因此,只有一个comeBack
函数在Gandalf
的所有实例中共享。这不是更好吗?
本质上认为你的第一个例子是这样的:
var gandalfPrototype = {
create: function() {
var gandalf = Object.create(this);
gandalf.color = "grey";
return gandalf;
},
comeBack: function() {
this.color = "white";
return this;
}
};
var gandalf = gandalfPrototype.create(); // there's only one comeBack function
同样你的第二个例子是相同的:
var gandalfPrototype = {
create: function() {
var gandalf = Object.create(this);
gandalf.color = "grey";
gandalf.comeBack = function() {
this.color = "white";
return this;
};
return gandalf;
}
};
var gandalf = gandalfPrototype.create(); // there's 1 comeBack for each instance
请记住,当你一个函数之前使用new
给你打电话实际上是继承了该函数的prototype
。不是功能本身。
最后,我想说的(因为我J.R.R.托尔金的忠实粉丝),这是我会写代码的方式:
var wizard = {
create: function (color) {
var wizard = Object.create(this);
wizard.color = color;
return wizard;
}
};
var gandalf = wizard.create("grey");
gandalf.comeBack = function() {
this.color = "white";
return this;
};
var saruman = wizard.create("white");
var radagast = wizard.create("brown");
感谢您阅读我的答案。
取决于你有多少Galdalfs。 – georg
[在Javascript中使用'prototype'与'this'?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) –
@ thg435取决于你有多少__Galdalfs__?你由于错字而毁了一个很棒的评论。 –