2009-11-20 66 views
7

什么是JavaScript类的原型?换句话说,就是什么是JavaScript中的原型?

Example.prototype.method {} 

Example.method{} 
限定实施例类时

之间的差异?

编辑:对于那些有兴趣,我发现了一个很好的解释(除了下面的回答)这里类方法和构造方法的区别:http://idhana.com/2009/07/13/constructor-vs-class-methods-in-javascript/

编辑2:完整的答案! http://blog.anselmbradford.com/2009/04/09/object-oriented-javascript-tip-creating-static-methods-instance-methods/

回答

5

不同之处在于您创建静态方法的后一个示例,如果Example是构造函数,则不会继承该静态方法。通过在构造函数的prototype属性中定义属性并使用关键字new创建对象,新创建的对象将继承构造函数的原型,从而可以访问这些方法。

一个例子是在内置的核心构造,如String定义..新创建的字符串有indexOf方法,因为有一个在String函数构造函数的原型中定义的方法

typeof String.prototype.indexOf // 'function' 

var name = 'John'; 
alert(name.indexOf('J')) // 0 

的下面的代码创建了一个函数构造函数,我们首先定义一个静态方法,创建一个对象,找出该对象没有getName方法,然后我们在原型中定义一个,并发现该对象确实有一个getName方法。

function Name(name) { 
    this.name = name; 
}; 
Name.getName = function(){}; 

var john = new Name(); 
typeof john.getName // undefined 

var john = new Name(); 
Name.prototype.getName = function(){ alert(this.name)}; 
typeof john.getName 

john.constructor.prototype.getName == john.getName // true 

所以要重申,继承ECMAScript中主要由定义在函数构造的原型的属性/方法来实现,例如将所有的核心构造诸如日期/数字/字符串具有方法中定义其相应的原型属性,它允许您在使用new关键字创建实例时使用这些方法。

请记住,新创建的对象具有constructor属性,该属性指向创建它的构造函数,我们可以直接访问prototype属性。我们创建的john对象并不直接拥有getName方法,因为解释器无法直接在对象上找到它,而是向上传递给构造函数,并在其原型中找到它。

而顺便说一句,我们并不需要创建john对象的新实例,正如您在创建初始构造函数后可以定义原型中的属性的其他答案中指出的那样,并且所有对象都会继承那些原型甚至在它们被创建之后。

静态方法不能依赖于上下文,不能依靠一类的特定实例,可以不依赖于this关键字因此这不会是一个静态方法:

function Name(name) { 
    this.name = name; 
    this.getName = function() { return this.name; } 
}; 

这将是一个静态方法的例子:

Name.getName = function() {}; 

,但有在做getName静态的,因为顾名思义它必须依赖于一个对象实例,以确定name属性是什么,你应该有更多的根儿绝对没有任何意义ic帮助函数像解析函数(如Date.parse)那样作为静态方法并在原型中定义实例方法,因为它们比在构造函数中定义this.foo = function(){}更有效。

+0

所以当我想要使用Name.getName = function(){}? – sepiroth 2009-11-20 03:21:14

+0

或者更确切地说,我何时可以在不使用原型定义的情况下为Name类定义方法(以及如何)? – sepiroth 2009-11-20 03:23:20

+0

'getName'将是一个公共方法,因此您可以在原型而不是静态方式上定义它,如果没有任何目的将其公开化或在原型中,则会定义一个静态方法。 – 2009-11-20 03:23:53

2

原型就像一个类的定义,但它可以动态更改。每当你实例化一个特定类型的对象时,它都会使用原型作为模板。

如果更改原型,则该类型的对象将具有这些更改。