2013-10-27 54 views
1

我正在写一个小手机游戏库,我不确定声明实例化函数对象的成员函数的最佳做法。的功能不JS成员函数的最佳实践

function Foo(id){ 
    this.id = id; 
    this.print = function(){ 
     console.log(this.id); 
    }; 
}; 

然而,这并不需要访问“私人”的成员函数:

举例来说,我可能会创建一个简单的对象有一个属性,一个方法来打印需要在函数中声明。我同样可以采写:

function print(){ 
    console.log(this.id); 
}; 

function Foo(id){ 
    this.id = id; 
    this.print = print; 
}; 

当该功能是通过富的一个实例调用,该实例成为this的背景下,这样的输出是在两种情况下是相同的。

我不完全确定如何分配内存与JS,我找不到任何我可以理解的具体事情,但在我看来,与第一个例子所有成员的Foo,包括打印函数在每次实例化时都会被复制 - 但是第二个函数只会获得一个指向预先声明的函数的指针,这会在创建更多Foo实例时节省更多内存。

我是否正确,如果我有这样做,是否有任何内存/性能好处?

+2

如果你不需要访问私有变量,最好的做法是将成员函数添加到原型。 – jfriend00

+0

希望JS编译器可以告诉第一个函数不引用任何闭包变量,因此它可以为所有实例重用相同的函数。 – Barmar

回答

3

在第一种情况下,使用Foo构造函数创建的每个对象都具有打印机功能的实例,这是正确的。一个简单的方法来避免,这是将它添加到Fooprototype

function Foo(id){ 
    this.id = id; 
}; 

Foo.prototype.print = function() { 
    console.log(this.id); 
}; 

或者:

function Foo(id){ 
    this.id = id; 
}; 

Foo.prototype = { 
    print: function() { 
     console.log(this.id); 
    } 
}; 

推荐阅读:

+0

干杯!不过,我还有一个问题 - 什么是好处,除了一种-的命名空间,使用原型在“绑定”(我想你可以说 - 他们不是全球因为他们是一个IIFE内)的功能呢?这种方式看起来很整洁,如果你想要其他不相关的对象来实现相同的方法。 – MickMalone1983

+0

如果你有两个不相关的类型,函数Foo(id){this.id = id; }'和'bar(id){this.id = id; }',并且它们以相同的方式打印,那么您可以将相同的打印功能添加到两种类型的原型中:'Foo.prototype.print = Bar.prototype.print = function(){console.log(this.id ); };'。方法的好处是它们可以通过'this'变量访问它们被调用的实例的属性。 – kol

+0

值得一提的是,将'print'作为一种方法并非绝对必要(但方便)。如果你有一个使用“this”的“未绑定”打印功能,例如'function print2(){console.log(this.id); }',那么你可以在'Foo'和'Bar'对象上调用它,而不需要将它添加到原型中:'var foo = new Foo(42); print2.call(foo);'和'var bar = new Bar(123); print2.call(巴);'。详细信息:https://developer.mozilla。org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call – kol