【发布时间】:2013-09-16 16:52:18
【问题描述】:
我想知道在闭包中使用函数构造函数时是否存在任何内存或性能问题?
这是一个粗略的例子,我知道有很多不同的更好的方法来写这个,我只是想提供一个例子,每个构造函数现在都可以访问闭包中的变量(农民、lastToSpeak 和动物) .
// usage: myFarm = new Farm(["Cow","Goat"],"Old MacDonald");
function Farm(animalList, farmer){
var animals = [],
lastToSpeak = "";
function Cow(){
this.speak = function(){
alert("I'm a Cow and I belong to "+farmer);
}
lastToSpeak = "A Cow";
}
function Sheep(){
this.speak = function(){
alert("I'm a Sheep and I belong to "+farmer);
}
lastToSpeak = "A Sheep";
}
function Goat(){
this.speak = function(){
alert("I'm a Goat and I belong to "+farmer);
}
lastToSpeak = "A Goat";
}
for(var i = 0; i < animalList.length; i++){
switch(animalList[i]){
case "Cow":
animals.push(new Cow());
break;
case "Sheep":
animals.push(new Sheep());
break;
case "Goat":
animals.push(new Goat());
break;
}
}
this.allSpeak = function(){
for(var i = 0; i < animals.length; i++){
animals[i].speak();
}
}
}
myFarm = new Farm(["Cow","Goat"],"Old MacDonald");
myFarm.allSpeak();
我猜在这个例子中它几乎没有什么区别,但是如果牛、绵羊和山羊更大更复杂,并且我们正在创建许多农场,这种方法会有什么缺点吗?
每次创建农场时都会将一组新的构造函数存储到内存中吗?
更新
所以我对 Kemal Dağ 所说的以及 Bergi 的评论感到满意。
如果我按照 Bergi 的建议更改代码以使用原型并在农场中传递,这似乎是更好的方法吗?
function Farm(animalList, farmer){
var animals = [],
lastToSpeak = "";
this.farmer = farmer;
for(var i = 0; i < animalList.length; i++){
switch(animalList[i]){
case "Cow":
animals.push(new this.Cow(this));
break;
case "Sheep":
animals.push(new this.Sheep(this));
break;
case "Goat":
animals.push(new this.Goat(this));
break;
}
}
this.allSpeak = function(){
for(var i = 0; i < animals.length; i++){
animals[i].speak();
}
}
}
Farm.prototype.Goat = function(farm){
this.speak = function(){
alert("I'm a Goat and I belong to "+farm.farmer);
}
farm.lastToSpeak = "A Goat";
}
Farm.prototype.Cow = function(farm){
this.speak = function(){
alert("I'm a Cow and I belong to "+farm.farmer);
}
farm.lastToSpeak = "A Cow";
}
Farm.prototype.Sheep = function(farm){
this.speak = function(){
alert("I'm a Sheep and I belong to "+farm.farmer);
}
farm.lastToSpeak = "A Sheep";
}
myFarm = new Farm(["Cow","Goat"],"Old MacDonald");
myFarm.allSpeak();
更新
我整理了一个小提琴而不是添加另一个版本到问题here。我已经完全分离了我的动物构造函数并将 speakAll() 移到原型中。我想我真的在寻找一种解决方案,它允许我在我的实例之间共享变量而不向全局范围添加任何内容。我最终决定将一个对象传递给每个实例而不是构造函数,这意味着我不必在构造函数上公开它们。谢谢各位。
【问题讨论】:
-
如果这些构造函数中的每一个都确实需要访问闭包变量(如您的情况下的
farmer),那很好。不过,将它们放在外面并将农场实例作为参数传递给它们可能会更方便。 -
您的最新更新可以正常工作而没有任何性能问题,但您也可以将 Goat、Cow 和 Sheep 函数定义为独立对象,并将它们注入到 Farm 对象中。除非您希望它们是私有的,否则它们完全不需要与 Farm 对象相关地定义。
标签: javascript performance memory