2012-08-07 129 views
3

我想知道这两种方法有什么区别。他们都工作,但我不明白,如果第二种方法可能有不良影响?JavaScript:在哪里放置原型功能

// A. Putting a prototype method outside the function declaration (what I would normally do) 
var Cat = function(){ 
} 

Cat.prototype.eat = function(){ 
    // implementation 
} 

// B. Putting a prototype method inside the function declaration (it works too but the scoping seems different) 
var Cat = function(){ 

    Cat.prototype.eat = function(){ 
     // implementation 
    } 
} 

回答

1

每个对象都有一个原型。原型继承允许你指定任意一个全新的原型(类似于经典的继承):

function Animal() { 
    this.numLegs = 4; 
} 
function Cat() { 
    // Implementation 
} 
Cat.prototype = new Animal(); 

var kitten = new Cat(); 
console.log(kitten.numLegs); // 4 

或者直接添加变量和方法,以当前类的原型:

function Cat() { 
    // Implementation 
} 
Cat.prototype.numLegs = 4; 

var kitten = new Cat(); 
console.log(kitten.numLegs); // 4 

你第二个示例简单地在每次启动Cat类时将Cat函数的eat函数重新分配给Cat原型,该函数无用,但不会占用任何内存,因为它只是覆盖旧值。

为什么这很有用?请记住,函数是对象。对于您的类的每个实例,在该类中定义的每个变量和函数都会占用它自己的内存。使用原型继承,您可以共享常用方法,从而不会占用每个实例的额外内存。

为什么这不是有用的?您无权访问私有变量。

请记住,这是不一样的事,作为一个静态方法,它可以声明为:

Cat.feed = function(kittens) { 
    for (var kitten in kittens) { 
     kitten.eat(); 
    } 
}; 
+0

感谢您的所有意见。我现在记得为什么我摆在这首先:我找不到从原型函数访问私有变量的方法。我现在明白你不应该那样做,因为私有变量只能从创建它们的范围访问。如果您需要访问原型中的变量,则应该使用'this'关键字而不是'var'来声明公共变量, – ChrisRich 2012-08-07 23:55:57

4

你可能想要做的第一个例子。两者都做同样的事情,虽然技术上第二个功能可以访问Cat的“私有”变量。不过,如果你想这样做,做了正确的方法是使用this

var Cat = function(){ 
    var a = 'hi'; 

    this.eat = function() { 
     alert(a); // Exists! 
    } 
} 

请记住,与上面的例子中,或与您的原“B”例如,吃的功能将不存在直到你用new Cat()实例化一个新的Cat。意思是,如果你只想在功能本身上调用Cat.eat(),就像实用方法一样,那么prototype的第一个例子就是要走的路。

+0

另外,2挡例子搞乱了可怕的,当你创建几个'猫'因为他们所有的'吃'方法都会访问最后一个'猫'的“私人”变种。 – Vatev 2012-08-07 07:46:15

+1

哈哈,我甚至没有考虑过。这将会导致一些杀手级的调试。 – 2012-08-07 07:57:46

+0

@Vatev - 你不能在它们声明的函数之外访问“私有”变量。使用'this'声明的变量是公共的,并且可以在构造函数和原型方法中以'this.var'方式访问。 – Wex 2012-08-07 08:02:20