Sometimes techniques like this is used to keep variable reference or create singleton. In this way we will call createVariable one time only.
What are the pros and cons of this approach?
function createVariable() {
// usually here may be some long asynchronous task
//
return true;
}
function useVariable() {
if(!useVariable.someVar) {
useVariable.someVar = createVariable();
}
// do something with useVariable.someVar
}
// we will call useVariable several times.
// The idea is to call createVariable
// one time only.
useVariable();
useVariable();
useVariable();
I am grateful to all ideas and recommendations. I don't want to create a singleton. Just want to keep variable reference on function level. Without
pollute the global scope.
What are the pros and cons of this approach?
The approach is okay, although I question the need for it as higher-level design question.
The implementation has a couple of issues:
If someVar contains a falsey value, you'll recreate it when you shouldn't. To check if you've previously created it, use if(!useVariable.hasOwnProperty("someVar")) { rather than if(!useVariable.someVar) {.
The falsey values are 0, "", NaN, undefined, null, and of course, false. (All other values are "truthy".)
Functions have some built-in properties, both their own (name, length) and ones they get from their prototypes (various methods, mostly). So if your variables have names like name, length, call, and so on, you'll mistakenly think you've created them when you haven't as createVariable will already have those properties with truthy values (in your createVariable case). You can work around that by adding a prefix of some kind, or using a separate object as a map (although objects inherit properties, too, so you'd still probably need a prefix), or if you were using ES2015+, you could use a Map.
You've said you only want to create the variable once and "not pollute the global scope" (which is a good thing to avoid). I do that by just wrapping my code in a scoping function:
(function() {
var someVar = createSomeVar();
// My other code here
})();
That keeps the global namespace untouched, and creates only a single copy of someVar without the need for any particular plumbing.
Here is how you would create a singleton (from http://www.dofactory.com/javascript/singleton-design-pattern):
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
then use it like this
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
//You can see here that they are indeed the same instance
alert("Same instance? " + (instance1 === instance2));
NOTE: this took five seconds to find via Google: http://dofactory.com/javascript/singleton-design-pattern
Related
Stylistically, I prefer this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
};
To this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
};// var Filter = function(){...}
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?
I've used the first structure before with success, but I want to make sure I'm not setting myself for a debugging headache, or causing a fellow developer grief and aggravation due to bad coding practices.
Functionally, are there any drawbacks to structuring my code this way?
Will adding a prototypical method to a prototype object inside the
constructor function's body (i.e. before the constructor function's
expression statement closes) cause unexpected scoping issues?
Yes, there are drawbacks and unexpected scoping issues.
Assigning the prototype over and over to a locally defined function, both repeats that assignment and creates a new function object each time. The earlier assignments will be garbage collected since they are no longer referenced, but it's unnecessary work in both runtime execution of the constructor and in terms of garbage collection compared to the second code block.
There are unexpected scoping issues in some circumstances. See the Counter example at the end of my answer for an explicit example. If you refer to a local variable of the constructor from the prototype method, then your first example creates a potentially nasty bug in your code.
There are some other (more minor) differences. Your first scheme prohibits the use of the prototype outside the constructor as in:
Filter.prototype.checkProduct.apply(someFilterLikeObject, ...)
And, of course, if someone used:
Object.create(Filter.prototype)
without running the Filter constructor, that would also create a different result which is probably not as likely since it's reasonable to expect that something that uses the Filter prototype should run the Filter constructor in order to achieve expected results.
From a run-time performance point of view (performance of calling methods on the object), you would be better off with this:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
this.checkProduct = function( product ){
// run some checks
return is_match;
}
};
There are some Javascript "experts" who claim that the memory savings of using the prototype is no longer needed (I watched a video lecture about that a few days ago) so it's time to start using the better performance of methods directly on the object rather than the prototype. I don't know if I'm ready to advocate that myself yet, but it was an interesting point to think about.
The biggest disadvantage of your first method I can think of is that it's really, really easy to make a nasty programming mistake. If you happen to think you can take advantage of the fact that the prototype method can now see local variables of the constructor, you will quickly shoot yourself in the foot as soon as you have more than one instance of your object. Imagine this circumstance:
var Counter = function(initialValue){
var value = initialValue;
// product is a JSON object
Counter.prototype.get = function() {
return value++;
}
};
var c1 = new Counter(0);
var c2 = new Counter(10);
console.log(c1.get()); // outputs 10, should output 0
Demonstration of the problem: http://jsfiddle.net/jfriend00/c7natr3d/
This is because, while it looks like the get method forms a closure and has access to the instance variables that are local variables of the constructor, it doesn't work that way in practice. Because all instances share the same prototype object, each new instance of the Counter object creates a new instance of the get function (which has access to the constructor local variables of the just created instance) and assigns it to the prototype, so now all instances have a get method that accesses the local variables of the constructor of the last instance created. It's a programming disaster as this is likely never what was intended and could easily be a head scratcher to figure out what went wrong and why.
While the other answers have focused on the things that are wrong with assigning to the prototype from inside the constructor, I'll focus on your first statement:
Stylistically, I prefer this structure
Probably you like the clean encapsulation that this notation offers - everything that belongs to the class is properly "scoped" to it by the {} block. (of course, the fallacy is that it is scoped to each run of the constructor function).
I suggest you take at the (revealing) module patterns that JavaScript offers. You get a much more explicit structure, standalone constructor declaration, class-scoped private variables, and everything properly encapsulated in a block:
var Filter = (function() {
function Filter(category, value) { // the constructor
this.category = category;
this.value = value;
}
// product is a JSON object
Filter.prototype.checkProduct = function(product) {
// run some checks
return is_match;
};
return Filter;
}());
The first example code kind of misses the purpose of the prototype. You will be recreating checkProduct method for each instance. While it will be defined only on the prototype, and will not consume memory for each instance, it will still take time.
If you wish to encapsulate the class you can check for the method's existence before stating the checkProduct method:
if(!Filter.prototype.checkProduct) {
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
}
There is one more thing you should consider. That anonymous function's closure now has access to all variables inside the constructor, so it might be tempting to access them, but that will lead you down a rabbit hole, as that function will only be privy to a single instance's closure. In your example it will be the last instance, and in my example it will be the first.
Biggest disadvantage of your code is closing possibility to override your methods.
If I write:
Filter.prototype.checkProduct = function( product ){
// run some checks
return different_result;
}
var a = new Filter(p1,p2);
a.checkProduct(product);
The result will be different than expected as original function will be called, not my.
In first example Filter prototype is not filled with functions until Filter is invoked at least once. What if somebody tries to inherit Filter prototypically? Using either nodejs'
function ExtendedFilter() {};
util.inherit(ExtendedFilter, Filter);
or Object.create:
function ExtendedFilter() {};
ExtendedFilter.prototype = Object.create(Filter.prototype);
always ends up with empty prototype in prototype chain if forgot or didn't know to invoke Filter first.
Just FYI, you cannot do this safely either:
function Constr(){
const privateVar = 'this var is private';
this.__proto__.getPrivateVar = function(){
return privateVar;
};
}
the reason is because Constr.prototype === this.__proto__, so you will have the same misbehavior.
Stylistically, I prefer this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
};
To this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
};// var Filter = function(){...}
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?
I've used the first structure before with success, but I want to make sure I'm not setting myself for a debugging headache, or causing a fellow developer grief and aggravation due to bad coding practices.
Functionally, are there any drawbacks to structuring my code this way?
Will adding a prototypical method to a prototype object inside the
constructor function's body (i.e. before the constructor function's
expression statement closes) cause unexpected scoping issues?
Yes, there are drawbacks and unexpected scoping issues.
Assigning the prototype over and over to a locally defined function, both repeats that assignment and creates a new function object each time. The earlier assignments will be garbage collected since they are no longer referenced, but it's unnecessary work in both runtime execution of the constructor and in terms of garbage collection compared to the second code block.
There are unexpected scoping issues in some circumstances. See the Counter example at the end of my answer for an explicit example. If you refer to a local variable of the constructor from the prototype method, then your first example creates a potentially nasty bug in your code.
There are some other (more minor) differences. Your first scheme prohibits the use of the prototype outside the constructor as in:
Filter.prototype.checkProduct.apply(someFilterLikeObject, ...)
And, of course, if someone used:
Object.create(Filter.prototype)
without running the Filter constructor, that would also create a different result which is probably not as likely since it's reasonable to expect that something that uses the Filter prototype should run the Filter constructor in order to achieve expected results.
From a run-time performance point of view (performance of calling methods on the object), you would be better off with this:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
this.checkProduct = function( product ){
// run some checks
return is_match;
}
};
There are some Javascript "experts" who claim that the memory savings of using the prototype is no longer needed (I watched a video lecture about that a few days ago) so it's time to start using the better performance of methods directly on the object rather than the prototype. I don't know if I'm ready to advocate that myself yet, but it was an interesting point to think about.
The biggest disadvantage of your first method I can think of is that it's really, really easy to make a nasty programming mistake. If you happen to think you can take advantage of the fact that the prototype method can now see local variables of the constructor, you will quickly shoot yourself in the foot as soon as you have more than one instance of your object. Imagine this circumstance:
var Counter = function(initialValue){
var value = initialValue;
// product is a JSON object
Counter.prototype.get = function() {
return value++;
}
};
var c1 = new Counter(0);
var c2 = new Counter(10);
console.log(c1.get()); // outputs 10, should output 0
Demonstration of the problem: http://jsfiddle.net/jfriend00/c7natr3d/
This is because, while it looks like the get method forms a closure and has access to the instance variables that are local variables of the constructor, it doesn't work that way in practice. Because all instances share the same prototype object, each new instance of the Counter object creates a new instance of the get function (which has access to the constructor local variables of the just created instance) and assigns it to the prototype, so now all instances have a get method that accesses the local variables of the constructor of the last instance created. It's a programming disaster as this is likely never what was intended and could easily be a head scratcher to figure out what went wrong and why.
While the other answers have focused on the things that are wrong with assigning to the prototype from inside the constructor, I'll focus on your first statement:
Stylistically, I prefer this structure
Probably you like the clean encapsulation that this notation offers - everything that belongs to the class is properly "scoped" to it by the {} block. (of course, the fallacy is that it is scoped to each run of the constructor function).
I suggest you take at the (revealing) module patterns that JavaScript offers. You get a much more explicit structure, standalone constructor declaration, class-scoped private variables, and everything properly encapsulated in a block:
var Filter = (function() {
function Filter(category, value) { // the constructor
this.category = category;
this.value = value;
}
// product is a JSON object
Filter.prototype.checkProduct = function(product) {
// run some checks
return is_match;
};
return Filter;
}());
The first example code kind of misses the purpose of the prototype. You will be recreating checkProduct method for each instance. While it will be defined only on the prototype, and will not consume memory for each instance, it will still take time.
If you wish to encapsulate the class you can check for the method's existence before stating the checkProduct method:
if(!Filter.prototype.checkProduct) {
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
}
There is one more thing you should consider. That anonymous function's closure now has access to all variables inside the constructor, so it might be tempting to access them, but that will lead you down a rabbit hole, as that function will only be privy to a single instance's closure. In your example it will be the last instance, and in my example it will be the first.
Biggest disadvantage of your code is closing possibility to override your methods.
If I write:
Filter.prototype.checkProduct = function( product ){
// run some checks
return different_result;
}
var a = new Filter(p1,p2);
a.checkProduct(product);
The result will be different than expected as original function will be called, not my.
In first example Filter prototype is not filled with functions until Filter is invoked at least once. What if somebody tries to inherit Filter prototypically? Using either nodejs'
function ExtendedFilter() {};
util.inherit(ExtendedFilter, Filter);
or Object.create:
function ExtendedFilter() {};
ExtendedFilter.prototype = Object.create(Filter.prototype);
always ends up with empty prototype in prototype chain if forgot or didn't know to invoke Filter first.
Just FYI, you cannot do this safely either:
function Constr(){
const privateVar = 'this var is private';
this.__proto__.getPrivateVar = function(){
return privateVar;
};
}
the reason is because Constr.prototype === this.__proto__, so you will have the same misbehavior.
The problem with functional inheritance is that if you want to create many instances then it will be slow because the functions have to be declared every time.
The problem with prototypal inheritance is that there is no way to truly have private variables.
Is it possible to mix these two together and get the best of both worlds? Here is my attempt using both prototypes and the singleton pattern combined:
var Animal = (function () {
var secret = "My Secret";
var _Animal = function (type) {
this.type = type;
}
_Animal.prototype = {
some_property: 123,
getSecret: function () {
return secret;
}
};
return _Animal;
}());
var cat = new Animal("cat");
cat.some_property; // 123
cat.type; // "cat"
cat.getSecret(); // "My Secret"
Is there any drawbacks of using this pattern? Security? Efficiency? Is there a similar pattern out there that already exists?
Your pattern is totally fine.
There are a few things that you'd want to keep in mind, here.
Primarily, the functions and variables which are created in the outermost closure will behave like private static methods/members in other languages (except in how they're actually called, syntactically).
If you use the prototype paradigm, creating private-static methods/members is impossible, of course.
You could further create public-static members/methods by appending them to your inner constructor, before returning it to the outer scope:
var Class = (function () {
var private_static = function () {},
public_static = function () {},
Class = function () {
var private_method = function () { private_static(); };
this.method = function () { private_method(); };
};
Class.static = public_static;
return Class;
}());
Class.static(); // calls `public_static`
var instance = new Class();
instance.method();
// calls instance's `private_method()`, which in turn calls the shared `private_static();`
Keep in mind that if you're intending to use "static" functions this way, that they have absolutely no access to the internal state of an instance, and as such, if you do use them, you'll need to pass them anything they require, and you'll have to collect the return statement (or modify object properties/array elements from inside).
Also, from inside of any instance, given the code above, public_static and Class.static(); are both totally valid ways of calling the public function, because it's not actually a static, but simply a function within a closure, which also happens to have been added as a property of another object which is also within the instance's scope-chain.
As an added bonus:
Even if malicious code DID start attacking your public static methods (Class.static) in hopes of hijacking your internals, any changes to the Class.static property would not affect the enclosed public_static function, so by calling the internal version, your instances would still be hack-safe as far as keeping people out of the private stuff...
If another module was depending on an instance, and that instance's public methods had been tampered with, and the other module just trusted everything it was given... ...well, shame on that module's creator -- but at least your stuff is secure.
Hooray for replicating the functionality of other languages, using little more than closure.
Is it possible to mix functional and prototypical inheritance together and get the best of both worlds?
Yes. And you should do it. Instead of initializing that as {}, you'd use Object.create to inherit from some proto object where all the non-priviliged methods are placed. However, inheriting from such a "class" won't be simple, and you soon end up with code that looks more like the pseudo-classical approach - even if using a factory.
My attempt using both prototypes and the singleton pattern combined. Is there a similar pattern out there that already exists?
OK, but that's something different from the above? Actually, this is known as the "Revealing Prototype Pattern", a combination of the Module Pattern and the Prototype Pattern.
Any drawbacks of using this pattern?
No, it's fine. Only for your example it is a bit unnecessary, and since your secret is kind of a static variable it doesn't make much sense to me accessing it from an instance method. Shorter:
function Animal(type) {
this.type = type;
}
Animal.prototype.some_property = 123;
Animal.getSecret = function() {
return "My Secret";
};
I have a simple global object with a get and set function. JSlint is not liking that I am using "this" in the get and set function because it violates "use strict". What would I replace "this" with so that it would not violate "use strict" (i.e. how go I reference the same thing "this" is referencing without using "this")?
function fnDirty() {
"use strict";
var bIsdirty = false;
this.get_bIsdirty = function() {return bIsdirty; };
this.set_bIsdirty = function(x) {bIsdirty = x; };
}
var GV_oDirty = new fnDirty();
By convention, constructor functions begin with capital letters. JSLint will allow use of this in strict mode if you are in a constructor function but yours begins with a lowercase letter so it does not get recognized as a constructor.
function FnDirty() {
//your code
}
To answer your remaining question: "What is the roundabout way of doing this without a constructor?"
Brian had the right-ish idea -- but what he was really creating was a singular object with private properties, rather than a factory.
So to that end, if you wanted a function which granted each instance of the "class" its own unique copy of the private property, you could do this (I'm going to illustrate an actual class of something more useful than "Foo" and "Bar", to better-illustrate the concept -- it should be very simple to recompose this into whatever your intended use is):
var makeWallet = function (starting_amount) {
var amount = starting_amount,
overdraft = 1000,
addAmount = function (added_funds) { amount += added_funds; },
deductAmount = function (extracted_amound) {
if (is_sufficient_funds(amount, overdraft, extracted_amount)) {
amount -= extracted_amount;
return makeWallet(extracted_amount);
}
},
// other needed public/helper methods here...
// checkBalance(), is_sufficient_funds(), etc...
public_interface = {
// add all public-API methods you need here
addFunds : addAmount,
deductFunds : deductAmount
};
return public_interface;
};
Now, you've got a function which will return an object. Each object has methods which access that object's own "private" (ie: closed-over) amount variable, which is unique to those methods and only accessible to those methods.
Whether you build the functions as vars in the private scope, or build them as function declarations in the private scope, or put them directly into a return { func1 : () {...},... }; is irrelevant, as long as they're defined inside of that function when it's called (ie: not on the prototype chain -- which you CAN'T use in this pattern, anyway -- you will NOT call this function with new).
Okay, so that's all well and good. You've now got a working wallet-maker (without the security and user-features, yadda-yadda... ...homework).
But what if you wanted to add PRIVATE STATIC members to that?
What if you needed to keep track of serial keys, so that you could issue bank cards to people? Or you needed to track the branch-number? This is where Brian's IIFE comes into play. Except that instead of returning the finished wallet object, it's going to return the wallet FACTORY.
var makeWallet = (function () {
var serial_num = 0,
branch_num = "A011002z";
function walletMaker = function (starting_amount) {
/*same function as before, except that you ALSO call:
serial_num += 1; in the construction of the wallet, and assign the id */
var id = serial_num += 1;
return wallet;
}
// then you return the wallet-factory
// which becomes the new value of the outer function
return walletMaker;
}());
Now you've got static properties (in the outermost closure, that the wallet-factory will have permanent access to, as "static" members), AND you have instance-based private members, which inner-methods, added during the creation of the instance-object, will have complete access to.
The only downsides to this are:
Lose the prototype ability for this particular class, because you aren't using a constructor. Meh. If your objects need this setup, then it's worth not having it...
...if they don't, and public-everything is cool, then just use a constructor, and prototype -- or just build inline objects, with no methods, and build services (functions) to operate on each similarly-built object.
If you build all objects this way, you're going to suffer a memory penalty, when you make thousands of these, or tens of thousands of these objects, each with their own copies of functions (to enclose the private references). Again, this is the price you pay for the functionality. Take the memory hit where security/clean interfaces are a must, and don't, where you don't need to.
Also goes without saying, but avoid using this in financial-institutions, as client-facing code isn't the best place to trust with the power to add and remove real money...
Hope that clears things up.
You can use an alternative approach:
var fnDirty = (function() {
var _isDirty = false;
return {
get_dirty: function() { return _isDirty; },
set_dirty: function(val) { _isDirty = value; }
};
})();
What is the difference between below approaches for adding methods to an object:
// Appending methods to a function using nested functions
var myObj1 = {
myMethod : function() {
console.log('myObj1.myMethod was called');
},
myOtherMethod : function() {
},
myOtherOtherMethod : function() {
}
}
// Appending methods to a function using the dot operator:
var myObj2 = {};
myObj2.myMethod = function(){
console.log('myObj2.myMethod was called');
}
myObj2.myOtherMethod = function(){
}
myObj2.myOtherOtherMethod = function(){
}
myObj1.myMethod(); // myObj1.myMethod was called
myObj2.myMethod(); // myObj2.myMethod was called
Both do the same thing. Besides the different syntax, is one approach preferred over the other? From my point of view, both approaches simply add methods (or function if you like) to an object.
http://jsfiddle.net/NK35z/
The two are semantically identical. The object literal syntax is preferred since it is more clear what you are doing and it also gives the JavaScript engine a chance to optimize the result.
There is no difference between both those ways of declaring objects/functions. If you mean static methods as in 'they don't change', that will work great.
They are not static methods in the traditional sense. Every time you create an object like that, it will have its own unique representation of it in memory. This means instead of one function in memory, you will have one function for each instance of that object (n copies of the function).
In order to make static methods (in the classical OOP sense, methods shared by a class (in JavaScript there are no classes, so objects using the same constructor/prototype) that do not require an instance), you can't really do it. But if you want the functions to only occupy one space in memory, you must use the Constructor Pattern:
function Foo()
{
//we won't assign any properties here.
}
Foo.prototype.method1 = function(var1, var2){
//don't use `this` here if you want the method to be truly static.
//static methods shouldn't try and access instance members.
};
Foo.prototype.method2 = function(var2, var3){
//whatever goes here
};
// Methods on the prototype are shared by all objects of foo, so we can create a new Foo
var f = new Foo();
foo.method1(1,2); // also works.
As others have said, there's no practical difference. Adding properties in a object literal makes sense where you know everything up front and can just assigne values. Adding properties one at a time make sense where you need to to some work before adding the method, e.g.:
var obj = {
/* define some stuff here */
};
if ( whatever ) {
obj.fn = function(){/* logic A */}
} else {
obj.fn = function(){/* logic B */}
}
There is no right or wrong way, use whatever suits best in each case. It's ok to use both for the same object.
They are exactly the same. You'll have to use the dot/square brackets accessor when you don't want to overwrite properties/methods that already exist on the object.