我想知道重写方法与原型和没有原型之间的区别。考虑:
示例1:
function Animal() {
this.sleep = function () {
alert("animal sleeping");
};
this.eat = function () {
alert("animal eating");
};
}
function Dog() {
this.eat = function () {
alert("Dog eating");
};
}
Dog.prototype = new Animal;
var dog = new Dog;
dog.eat();
示例2:
function Animal() { }
function Dog() { }
Animal.prototype.sleep = function () {
alert("animal sleeping");
};
Animal.prototype.eat = function () {
alert("animal eating");
};
Dog.prototype = new Animal;
Dog.prototype.eat = function () {
alert("Dog eating");
};
var dog = new Dog;
dog.eat();
我觉得这两个例子产生的效果与Dog
类覆盖Animal
类的eat方法相同。或者有什么不同的事情发生?
答案 0 :(得分:10)
在第一种方法中,每个Animal
实例都会获得自己的sleep
和eat
方法实现。
在第二个模型中,所有实例将共享sleep
和eat
方法的相同实例。
第二种模式更好,因为我们可以分享方法。
答案 1 :(得分:6)
正如Arun在第一个示例中提到的那样,您为每个新实例创建了sleep
和eat
函数。在第二个示例中,只有一个sleep
和eat
函数在所有实例之间共享。
在这种情况下,第二种方法更好,但最好知道何时使用第一种方法以及何时使用第二种方法。首先是一点理论:
注意: JavaScript中有四种变量 - private
,public
,shared
和static
。
私有变量在定义它们的函数之外是不可访问的。例如:
function f() {
var x; // this is a private variable
}
公共变量在函数内的this
对象上定义。例如:
function f() {
this.x; // this is a public variable
}
共享变量在函数的prototype
上共享。例如:
function f() {}
f.prototype.x; // this is a shared variable
静态变量是函数本身的属性。例如:
function f() {}
f.x; // this is a static variable
大多数情况下,最好将构造函数的方法声明为共享方法,因为构造函数的所有实例都共享它们。但是,如果您的方法需要访问私有变量,则必须将其声明为公共方法本身。
注意:这是我自己的命名法。没有多少JavaScript程序员遵守它。其他人似乎遵循道格拉斯·克罗克福德的命名法:http://javascript.crockford.com/private.html
要了解有关JavaScript中原型继承的更多信息,请阅读以下答案:https://stackoverflow.com/a/8096017/783743
答案 2 :(得分:0)
在您的第一个示例中,每个新的Dog
实例都有自己的eat
方法,在第二个示例中,eat
上只有一个Dog.prototype
方法,在Arun所提及的所有Dog
实例之间共享。
这是这两者之间唯一的“棘手”差异。但是在prototype
上定义方法总是更好,以避免高内存消耗和泄漏。
答案 3 :(得分:0)
第一个示例中的方法在对象实例中定义。
您正在将Dog
原型设置为新的Animal
实例,因此Dog
将从sleep
继承eat
和Animal
个函数。然后你在eat
构造函数中定义(不是 OVERRIDING )Dog
方法作为实例方法,这将 HIDE eat
个实例中的继承Dog
方法。
考虑以下示例:
function LittleDog() { }
LittleDog.prototype = Object.create(Dog.prototype);
(new LittleDog()).eat();
上面的代码会在第一个示例中使用您的代码提醒animal eating
。
并使用第二个代码提醒Dog eating
。