Javascript-在闭包中使用函数构造函数是个坏主意吗?
我想知道在闭包中使用函数构造函数时是否存在内存或性能问题 这是一个粗略的例子,我知道有很多不同的更好的方法来编写它,我只是想提供一个例子,每个构造函数现在都可以访问闭包中的变量(farmer、lastToSpeak和animals)Javascript-在闭包中使用函数构造函数是个坏主意吗?,javascript,performance,memory,Javascript,Performance,Memory,我想知道在闭包中使用函数构造函数时是否存在内存或性能问题 这是一个粗略的例子,我知道有很多不同的更好的方法来编写它,我只是想提供一个例子,每个构造函数现在都可以访问闭包中的变量(farmer、lastToSpeak和animals) //用法:myFarm=新农场([“奶牛”、“山羊”、“老麦当劳”); 功能农场(动物学家、农民){ 变量=[], lastToSpeak=“”; 函数Cow(){ this.speak=函数(){ 警惕(“我是一头牛,我属于”+农夫); } lastToSpeak
//用法:myFarm=新农场([“奶牛”、“山羊”、“老麦当劳”);
功能农场(动物学家、农民){
变量=[],
lastToSpeak=“”;
函数Cow(){
this.speak=函数(){
警惕(“我是一头牛,我属于”+农夫);
}
lastToSpeak=“一头牛”;
}
功能羊(){
this.speak=函数(){
警惕(“我是一只羊,我属于”+农夫);
}
lastToSpeak=“绵羊”;
}
功能山羊(){
this.speak=函数(){
警惕(“我是一只山羊,我属于”+农夫);
}
lastToSpeak=“山羊”;
}
对于(变量i=0;i
我猜在这个例子中没有什么区别,但是如果牛、羊和山羊都更大、更复杂,并且我们创建了很多农场,这种方法会有任何缺点吗
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();
是否每次创建场时都会将一组新的构造函数存储到内存中
更新
因此,我对凯末尔·达奥所说的以及贝尔吉的评论感到高兴
如果我像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();
功能农场(动物学家、农民){
变量=[],
lastToSpeak=“”;
这个农民=农民;
对于(变量i=0;i
更新
我编造了一把小提琴,而不是在这个问题上添加另一个版本。我已经完全分离了我的动物构造器,并将speakAll()移到了原型中。我想我真的在寻找一种解决方案,它允许我在不向全局范围添加任何内容的情况下跨实例共享变量。我最终决定将对象传递给每个实例,而不是构造函数,这意味着我不必在构造函数上公开它们。谢谢大家。在javascript中,每个函数本身都是一个对象,所以你的问题的答案是肯定的。每次创建农场对象时,都会创建其所有私有方法,例如:Cow、Sheep、Goat 要防止这种情况,请在农场对象的原型中创建函数。这可以防止为这些函数重新分配内存,但它们会立即成为公共函数。见:
Farm.prototype.Goat = function(farmer){
this.speak = function(){
alert("I'm a Goat and I belong to "+farmer);
}
this.lastToSpeak = "A Goat";
}
你必须决定私人功能是否对你至关重要?那么原型方法就更好了
但请记住,在javascript中使用原型有点棘手,所以我不得不修改代码的某些方面,您可以看到一个工作示例
在该示例中,您会发现this.lastToSpeak
赋值基本上是错误的。因为您将在农场对象的原型处创建的函数用作对象构造函数本身。然后,这个
变成了对Goat对象而不是Farm对象的引用,所以如果您想引用父Farm对象,您可能会将引用传递给parent to Goat构造函数。请记住,原型继承与标准类继承完全不同,但您几乎可以模仿您想要的任何行为
是否每次创建场时都会将一组新的构造函数存储到内存中
对。但是,如果他们真的需要访问闭包变量(比如lastToSpeak
),这是合理的,就像特权方法一样。拥有私有构造函数可能有点奇怪,但可能是必需的
当您处理一组类似(但范围不同)的构造函数时,为它们提供一个公共原型对象可能是一种性能优化。如果原型方法也不需要访问闭包变量,则使用场
构造函数外部的静态对象,并将其分配给每个特权构造函数
我将代码改为使用原型,这似乎是更好的方法吗
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();
不是这样的。构造函数不应该是实例方法,将它们放在原型对象上是很奇怪的。最好把它们放在农场上