Note that there are some explanatory texts on larger screens.

plurals
  1. POJavascript - Is it a bad idea to use function constructors within closures?
    primarykey
    data
    text
    <p>I'm wondering if there are any memory or performance issues when using function constructors within a closure?</p> <p>Here is a crude example, I know there are a tonne of different and better ways to write this, I just wanted to provide an example where each constructor now has access to variable in the closure (farmer,lastToSpeak and the animals).</p> <pre><code>// 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 &lt; 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 &lt; animals.length; i++){ animals[i].speak(); } } } myFarm = new Farm(["Cow","Goat"],"Old MacDonald"); myFarm.allSpeak(); </code></pre> <p>I'm guessing in this example it makes little difference, but if the cow,sheep and goat were much larger and complex and we were creating lots of farms would there be any disadvantages to this approach?</p> <p>Will a new set of constructor functions be stored to memory every time a farm is created?</p> <p><strong>UPDATE</strong></p> <p>So i'm happy with what Kemal Dağ said and also the comment from Bergi. </p> <p>If I changed the code to use prototypes and passed in the farm as Bergi suggests, does that seem like the better approach?</p> <pre><code>function Farm(animalList, farmer){ var animals = [], lastToSpeak = ""; this.farmer = farmer; for(var i = 0; i &lt; 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 &lt; 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(); </code></pre> <p><strong>UPDATE</strong></p> <p>I put together a fiddle rather than add another version to the question <a href="http://jsfiddle.net/QR38A/2/" rel="nofollow">here</a>. I've separated my animal constructors completely and moved speakAll() to the prototype. I think I was really looking for a solution that allowed me to share variables across my instances without adding anything to the global scope. I finally decided to pass an object to each instance rather than the constructor, meaning I don't have to make them public on the constructor. Thanks Guys.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload