据我所知,有两种主要方法可以在javascript中为对象创建函数。他们是:
方法A,在构造函数中创建:
function MyObject() {
this.myFunc1 = function() {
...
}
this.myFunc2 = function() {
...
}
...
}
方法B,将其添加到原型中:
function MyObject() {
...
}
MyObject.prototype.myFunc1 = function() {
...
}
MyObject.prototype.myFunc2 = function() {
....
}
显然,如果你这样做了:
MyObject.myFunc3 = function() {
....
}
然后myFunc3
将与MyObject本身相关联,而不是使用new
关键字创建的任何新对象。为清楚起见,我们将其称为方法C,即使它不适用于使用new
关键字创建新对象。
所以,我想知道两者之间的区别是什么。据我所知,它们在逻辑上具有相同的效果,即使机器上发生的事情有所不同。
如果我猜测我会说唯一真正的区别是当你在方法A中的构造函数中定义它们时,它会为每个创建的对象创建一个全新的函数对象,而方法B只保留一个它的副本(在MyObject中),它指的是它被调用的任何时间。如果是这种情况,你为什么要以另一种方式做到这一点。否则,方法A和方法B之间有什么区别。
答案 0 :(得分:4)
为每个对象提供单独的函数的优点是,您可以关闭构造函数中的变量,基本上允许“私有数据”。
function MyObject(a,b) {
var n = a + b; //private variable
this.myFunc1 = function() {
console.log(n);
}
};
VS
function MyObject(a,b) {
this.n = a + b; //public variable
}
MyObject.prototype.myFunc1 = function() {
console.log(this.n);
}
这是否是一个好主意取决于你问谁。我个人的立场是在实际使用原型时保留构造函数,如选项#2和使用简单函数(比如make_my_object(a,b)
)在使用闭包时,如选项#1。
答案 1 :(得分:2)
这个想法是你可以随时修改原型,所有类型的对象(甚至修改前创建的对象)都将继承更改。这是因为,正如您所提到的,原型不会随每个新实例一起复制。
答案 2 :(得分:0)
方法A中的MyObject
是内部函数的实例。
假设:
MyObject.MyFunc1(); // will not work
var obj = new MyObject();
obj.MyFunc1(); // will work
所以这和其他语言的任何类都一样。然而,描述类及其用法的有用性超出了这个问题。
另请注意:
function MyObject() {
var privateVar = "foo";
this.publicProperty = "bar";
// public function
this.publicFunc = function() {
...
}
// private function
function privateFunc () {
...
}
}
对于方法B ,它与方法A相同,唯一的区别是原型设计是一种创建对象的方式。有些人将原型用于可读性或偏好。 原型的主要优点是您可以在不触及原始源的情况下扩展现有对象。但是你需要小心。 (例如Prototype框架)
对于方法C ,您可以将它们称为静态函数。如你所说,可以通过引用像:
之类的对象来明确调用它们MyObject.MyFunc1();
所以使用哪一个取决于你正在处理的情况。