我想知道这两种方法有什么区别。它们都有效但我不明白第二种方法是否会产生不良影响?
// 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
}
}
答案 0 :(得分:4)
您可能想要做第一个例子。两者都做了完全相同的事情,虽然从技术上讲,第二个函数可以访问Cat的“私有”变量。但是,如果您想这样做,正确的方法是使用this
:
var Cat = function(){
var a = 'hi';
this.eat = function() {
alert(a); // Exists!
}
}
请记住,使用上面的示例或原始的“B”示例,在使用new Cat()
实例化新Cat之前,eat函数将不存在。这意味着,如果您只想在函数本身上调用Cat.eat()
,就像实用程序方法一样,那么第一个带有prototype
的示例就是可行的方法。
答案 1 :(得分: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
你的第二个例子只是在每次启动eat
类时都将Cat
函数重新分配给Cat原型,这是没用的,但是没有占用任何内存,因为它只是覆盖旧的值。
为什么这有用?请记住,函数是对象。对于类的每个实例,该类中定义的每个变量和函数都占用它自己的内存。使用原型继承,您可以共享常用方法,从而不占用每个实例的额外内存。
为什么这不是很有用?您无法访问私有变量。
请记住,这与 static 方法不同,后者可以声明为:
Cat.feed = function(kittens) {
for (var kitten in kittens) {
kitten.eat();
}
};