在第一个中,您只能创建对象一次,而在第二个中,您可以创建任意数量的对象。即第一个实际上是一个单例。
请注意,对于第二个来说,闭包并不适用。每次实例化它时,您都要重新创建函数,并浪费大量内存。原型对象旨在解决这个问题,您可以在函数范围之外仅创建一次函数,并且不会创建意外的闭包。
function foo2(){
this._bar = 0;
}
foo2.prototype = {
constructor: foo2,
getBar: function(){
return this._bar;
},
addOne: function(){
this._bar++;
},
addRandom:function(rand){
this._bar += rand;
}
};
那么:
var a = new foo2, b = new foo2, c = new foo2
创建三个实例,它们拥有自己的_bar
但共享相同的功能。
jsperf
你可以将所有这些与PHP进行“比较”,其中一些代码甚至无法运行,但在原则上是“等效”的:
var foo = (function(){
var bar = 0;
return {
getBar: function(){
return bar;
},
addOne: function(){
bar++;
},
addRandom: function(rand){
bar += rand;
}
}
})();
在 PHP 中,这大致相当于:
$foo = new stdClass;
$foo->bar = 0;
$foo->getBar = function(){
return $this->bar;
};
$foo->addOne = function(){
$this->bar++;
}
$foo->addRandom = function($rand){
$this->bar += $rand;
}
var foo2 = function(){
var bar = 0;
this.getBar = function(){
return bar;
};
this.addOne = function(){
bar++;
};
this.addRandom = function(rand){
bar += rand;
}
};
在 PHP 中,大致等同于:
Class foo2 {
public function __construct(){
$bar = 0;
$this->getBar = function(){
return $bar;
};
$this->addOne = function(){
$bar++;
};
$this->addRandom = function($rand){
$bar += rand;
};
}
}
function foo2(){
this._bar = 0;
}
foo2.prototype = {
constructor: foo2,
getBar: function(){
return this._bar;
},
addOne: function(){
this._bar++;
},
addRandom:function(rand){
this._bar += rand;
}
};
在PHP中,大致等同于以下代码:
Class foo2 {
public $_bar;
public function __construct(){
$this->_bar = 0;
}
public function getBar(){
return $this->_bar;
}
public function addOne(){
$this->_bar++
}
public function addRandom($rand){
$this->_bar += $rand;
}
}
...并且是上述三个示例中唯一接近面向对象编程的示例