2011-10-18 43 views
0

我有一个fiddle帮助我理解JavaScript原型和继承。评论讲述了这个故事。了解原型和增强

//From Douglas Crockford's "Javascript: the good parts": a helper to hide the "ugliness" of setting up a prototype 
Function.prototype.method = function(name,func) { 
    this.prototype[name] = func; 
    return this; 
} 

function SomeFunc(value) { 
    this.setValue(value); 
} 

//Inherit the function (to me this conceptually the same as adding a member to a class) 
SomeFunc.method('setValue', function (value) { 
    this.value = value; 
    return this; 
}); 

try 
{ 
SomeFunc(1); 
} 
catch(e) 
{ 
    alert(e); 
} 

为什么我会得到异常?我的笔记是否正确,因为JavaScript调用继承是古典程序员简单地向类中添加新成员?增强和继承有什么区别?

+0

一开始的情况下,看看[使用对象](https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects)和[继承和原型链](https://developer.mozilla.org/zh/JavaScript/Guide/Inheritance_constructor_prototype)。 –

+1

你在'SomeFunc(1)'之前忘了''''' – Kru

+0

@Kru - 修正了错误。为什么需要新的? –

回答

6

我的笔记正确的是JavaScript调用继承是古典程序员简单地向类添加一个新成员?

不,不是真的。在JavaScript中,我们有基于原型的继承。这意味着一个对象可以引用另一个对象,即其原型。无论何时访问对象的属性,都会搜索原型链以查找此属性。因此,如果该对象本身没有该属性,则会检查其原型是否属于该属性等等。

+------------+ +-------------+ 
| Instance | | Prototype | 
| __proto__ -+--->| __proto__ -+-->... 
| foo  | | bar  | 
+------------+ +-------------+ 

Instance兼备,所述foobar性质。

现在,如果你有一个构造函数,你可以创建很多引用同一个原型的实例(对象)。当您现在向该原型添加新属性时,所有实例也会拥有该属性(由于原型链)。

这通常是为了动态扩展实例而完成的,但这只是原型继承的一个结果,它不是继承本身。

增强和继承有什么区别?

继承可以将对象的原型设置为某个对象,以使其位于原型链中。扩充只是复制属性。对象将自己该属性则:

+------------+ 
| Instance | 
| __proto__ -+--->... 
| foo  |  
| bar  | 
+------------+ 

为什么我得到一个异常?

因为你打电话SomeFunc就像一个“正常”的功能,而不是像一个构造函数。在这种情况下,this将参考window,它没有setValue方法。

而是要与new operator [MDN]称呼它,创建一个新的实例:

var instance = new SomeFunc(1); 

如果这样调用,this将把它从构造函数的prototype财产继承一个空对象(SomeFunc.prototype) 。

MDN has a nice article about this and what it refers to in certain situations.

如果你看一下method是干什么的,你看,它增加了一个新的属性SomeFunc.prototypethisSomeFunc):

this.prototype[name] = func; 

事实上,是第一部分你的代码正在做的是我上面提到的:通过扩展Function.prototype,你可以为每个函数添加一个新的属性,这让你稍后可以调用SomeFunc.methods


延伸阅读:

+0

你忘了'新'。 ;)+1虽然。 – user113716

+1

谢谢...... D –

+1

......啊,我看到你正忙着制作你喜欢的图形插图。 :) – user113716

0

尝试,而不是:

new SomeFunc(1); 

,因为这是当工程样机