I come across singleton pattern, it's quite tricky to understand how to implement it, and I know some people would suggest to avoid it most of the time, so below is specific singleton variation that I find it easy to understand, but somehow I feel that this is not the best implementation of this pattern, can you guys suggest better form of this pattern.
var Foo = (function () {
var instance;
var _priVar = 2;
var log = function() {
console.log("Hello");
};
function Singleton(x, y) {
if (instance) {
return instance;
}
this.name = x;
this.age = y + _priVar;
this.log = log;
instance = this;
}
Singleton.getInstance = function () {
return instance || new Singleton();
}
return Singleton;
}());
and my goal is that when we do following
var a = new Foo("Bob", 24);
var b = new Foo();
var c = Foo();
var d = Foo.getInstance();
we will still get
a == b // true
a == c // true
a == d // true
a.name // 'Bob'
b.age // 26
c.log // 'Hello'
d.name // 'Bob'
The simplest singleton, also known as module pattern, consists of an object literal:
var foo = (function () {
var x = "Bob",
y = 24,
_priVar = 2;
function log() {
console.log("Hello");
}
return {
name: x,
age: y + _priVar,
log: log
};
}());
If you want to introduce lazy initialisation, you can use an extra getInstance function like in your implementation:
var getFoo = (function () {
var instance = null;
return function getFooInstance() {
if (instance) return instance;
var x = "Bob",
y = 24,
_priVar = 2;
function log() {
console.log("Hello");
}
return instance = {
name: x,
age: y + _priVar,
log: log
};
};
}());
A singleton should never use a constructor like in your code, that's just unnecessary. If you feel a need to pass arguments for initialisation, don't make it a singleton.
Related
Sorry for dump question I am new to js. I would like to override f2() function in D "class". But for some reason Fire Fox told me: "too much recursion". Could you please point me where recursion happening and how to make this code work as expected?
var B = function () {
};
B.prototype.f2 = function (x) {
return 2 * x;
};
var C = function () {
B.call(this);
};
var D = function () {
C.call(this);
};
D.prototype.f2 = function (x) {
return C.prototype.f2.call(this, x) * 7;
};
inherit(B, C);
inherit(C, D);
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var d = new D();
console.log(d.f2(3));
Two problems:
You need to set up the XYZ.prototype objects before you try to add properties to them. Since your inherit function creates them, you must ensure that you do things in the right order.
You have the order of the parent and child backward in your inherit calls. It's inherit(child, parent), not inherit(parent, child).
var B = function () {
};
B.prototype.f2 = function (x) {
return 2 * x;
};
var C = function () {
B.call(this);
};
inherit(C, B); // *** Moved and updated
var D = function () {
C.call(this);
};
inherit(D, C); // *** Moved and updated
D.prototype.f2 = function (x) {
return C.prototype.f2.call(this, x) * 7;
};
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var d = new D();
console.log(d.f2(3));
The ES2015 version, for comparison:
class B {
f2(x) {
return 2 * x;
}
}
class C extends B {
}
class D extends C {
f2(x) {
return super.f2(x) * 7;
}
}
const d = new D();
console.log(d.f2(3));
I am reading a book which contains the following example:
var composition1 = function(f, g) {
return function(x) {
return f(g(x));
}
};
Then the author writes: "...naive implementation of composition, because it does not take the execution context into account..."
So the preferred function is that one:
var composition2 = function(f, g) {
return function() {
return f.call(this, g.apply(this, arguments));
}
};
Followed by an entire example:
var composition2 = function composition2(f, g) {
return function() {
return f.call(this, g.apply(this, arguments));
}
};
var addFour = function addFour(x) {
return x + 4;
};
var timesSeven = function timesSeven(x) {
return x * 7;
};
var addFourtimesSeven2 = composition2(timesSeven, addFour);
var result2 = addFourtimesSeven2(2);
console.log(result2);
Could someone please explain to me why the composition2 function is the preferred one (maybe with an example)?
EDIT:
In the meantime i have tried to use methods as arguments as suggested, but it did not work. The result was NaN:
var composition1 = function composition1(f, g) {
return function(x) {
return f(g(x));
};
};
var composition2 = function composition2(f, g) {
return function() {
return f.call(this, g.apply(this, arguments));
}
};
var addFour = {
myMethod: function addFour(x) {
return x + this.number;
},
number: 4
};
var timesSeven = {
myMethod: function timesSeven(x) {
return x * this.number;
},
number: 7
};
var addFourtimesSeven1 = composition1(timesSeven.myMethod, addFour.myMethod);
var result1 = addFourtimesSeven1(2);
console.log(result1);
var addFourtimesSeven2 = composition2(timesSeven.myMethod, addFour.myMethod);
var result2 = addFourtimesSeven2(2);
console.log(result2);
This just answers what composition2 actually does:
composition2 is used when you want to keep this as context in the functions itself. The following example shows that the result is 60 by using data.a and data.b:
'use strict';
var multiply = function(value) {
return value * this.a;
}
var add = function(value) {
return value + this.b;
}
var data = {
a: 10,
b: 4,
func: composition2(multiply, add)
};
var result = data.func(2);
// uses 'data' as 'this' inside the 'add' and 'multiply' functions
// (2 + 4) * 10 = 60
But yet, it still breaks the following example (unfortunately):
'use strict';
function Foo() {
this.a = 10;
this.b = 4;
}
Foo.prototype.multiply = function(value) {
return value * this.a;
};
Foo.prototype.add = function(value) {
return value + this.b;
};
var foo = new Foo();
var func = composition2(foo.multiply, foo.add);
var result = func(2); // Uncaught TypeError: Cannot read property 'b' of undefined
Because the context of composition2 (this) is undefined (and is not called in any other way, such as .apply, .call or obj.func()), you'd end up with this being undefined in the functions as well.
On the other hand, we can give it another context by using the following code:
'use strict';
var foo = new Foo();
var data = {
a: 20,
b: 8,
func: composition2(foo.multiply, foo.add)
}
var result = data.func(2);
// uses 'data' as 'this'
// (2 + 8) * 10 = 200 :)
Or by explicitly setting the context:
'use strict';
var multiply = function(value) {
return value * this.a;
};
var add = function(value) {
return value + this.b;
};
var a = 20;
var b = 8;
var func = composition2(multiply, add);
// All the same
var result1 = this.func(2);
var result2 = func.call(this, 2);
var result3 = func.apply(this, [2]);
composition1 would not pass arguments other than the first to g()
If you do:
var composition1 = function(f, g) {
return function(x1, x2, x3) {
return f(g(x1, x2, x3));
}
};
the function will work for the first three arguments. If you however want it to work for an arbitrary number, you need to use Function.prototype.apply.
f.call(...) is used to set this as shown in Caramiriel's answer.
I disagree with the author.
Think of the use-case for function-composition. Most of the time I utilize function-composition for transformer-functions (pure functions; argument(s) in, result out and this is irrelevant).
2nd. Utilizing arguments the way he does it leads into a bad practice/dead end, because it implies that the function g() might depend on multiple arguments.
That means, that the composition I create is not composable anymore, because it might not get all arguments it needs.
composition that prevents composition; fail
(And as a side-effect: passing the arguments-object to any other function is a performance no-go, because the JS-engine can't optimize this anymore)
Take a look at the topic of partial application, usually misreferenced as currying in JS, wich is basically: unless all arguments are passed, the function returns another function that takes the remaining args; until I have all my arguments I need to process them.
Then you should rethink the way you implement argument-order, because this works best when you define them as configs-first, data-last.Example:
//a transformer: value in, lowercased string out
var toLowerCase = function(str){
return String(str).toLowerCase();
}
//the original function expects 3 arguments,
//two configs and the data to process.
var replace = curry(function(needle, heystack, str){
return String(str).replace(needle, heystack);
});
//now I pass a partially applied function to map() that only
//needs the data to process; this is really composable
arr.map( replace(/\s[A-Z]/g, toLowerCase) );
//or I create another utility by only applying the first argument
var replaceWhitespaceWith = replace(/\s+/g);
//and pass the remaining configs later
arr.map( replaceWhitespaceWith("-") );
A slightly different approach is to create functions that are, by design, not intended to get all arguments passed in one step, but one by one (or in meaningful groups)
var prepend = a => b => String(a) + String(b); //one by one
var substr = (from, to) => value => String(str).substr(from, to); //or grouped
arr.map( compose( prepend("foo"), substr(0, 5) ) );
arr.map( compose( prepend("bar"), substr(5) ) );
//and the `to`-argument is undefined; by intent
I don't intend to ever call such functions with all the arguments, all I want to pass them is their configs, and to get a function that does the job on the passed data/value.
Instead of substr(0, 5, someString), I would always write someString.substr(0, 5), so why take any efforts to make the last argument (data) applyable in the first call?
I am trying to simulate a simple Holder "class" in JavaScript with a "private" property that holds something and "public" getter and setter "methods" to access the value.
The approach exhibited by HolderA below is mentioned e.g. here. The other approach I more or less arrived at by mutation but I guess it must be recognizable as an idiom as well. I like it because it contains no this or prototype stuff and seems very elementary and functional. Is there a difference between the two?
The test code (I run it under nodejs) seems to suggest that the two approaches are identical except that in the first case the objects I get have typeof object whereas in the second function.
var test = function(o) {
var initialValueCorrect = (!(typeof o.getX()==='undefined'))&&(o.getX()===0);
var VALUE_TO_SET = 10;
o.setX(VALUE_TO_SET);
var getSetWorks = o.getX()===VALUE_TO_SET;
var xIsPrivate = (typeof o.x === 'undefined');
var xHasCorrectValue;
if (!xIsPrivate)
xHasCorrectValue = o.x === VALUE_TO_SET;
return {initialValueCorrect: initialValueCorrect,
getSetWorks : getSetWorks,
xIsPrivate: xIsPrivate,
xHasCorrectValue: xHasCorrectValue};
};
var HolderA = (function() {
function foo(x) {
this.getX = function() {
return x;
};
this.setX = function(_x) {
x = _x;
};
};
return foo;
})();
var createHolderB = (function() {
var x;
function foo(_x) {
x = _x;
return foo;
}
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
})();
var objects = [{object: new HolderA(0), name: "approach with constructor-invocation and 'this'"},
{object: createHolderB(0), name: "approach with normal function invocation and closed variable"}];
for (var i = 0; i<objects.length ; i++) {
var testResult = test(objects[i].object);
console.log('['+objects[i].name+']: the object is a: '+(typeof objects[i].object)
+'\n\n\t\t\t'+JSON.stringify(testResult)+'\n\n\n\n\n');
}
update
As Bergi has pointed out function createHolderB in my code above is plain wrong and only creates a singleton object. So, is not really a "constructor" function. To that end I've now created createHolderC which can be used to really create multiple objects with a hidden private property like this:
var objectC1 = createHolderC()(0);
Now, is there any material difference between HolderA and the createHolderC function or is the difference purely stylistic?
var createHolderC = function () {
return (function() {
var x;
function foo(_x) {
x = _x;
return foo;
};
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
})();
};
createHolderB does not create new holders like HolderA does. It's essentially a singleton pattern. You might also want to call it a module. Notice that createHolderB() === createHolderB.
createHolderC is still different from HolderA in that it returns function objects, not instances. You may see the differences better when you strip out the unnecessary IEFEs:
function HolderA(x) {
this.getX = function() {
return x;
};
this.setX = function(_x) {
x = _x;
};
// implicit `return this;` when called via `new`
}
function createHolderC() {
var x;
function foo(_x) {
x = _x;
return foo;
};
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
}
A typical factory would rather look like this:
function createHolderD(x) {
var foo = {};
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
}
(or even with return {getX: …, setX: …};), the only difference to HolderA is the prototypical inheritance then.
Basically both exhibits the private access behavior to the x variable. But the difference between those two are
Constructor function
var HolderA = (function() {
function foo(x) {
this.getX = function() {
return x;
};
this.setX = function(_x) {
x = _x;
};
};
return foo;
})();
This is a self executing function, where it returns Constructor foo.
That is the reason you are using new while creating this type of holder {object: new HolderA(0)
A function
var createHolderB = (function() {
var x;
function foo(_x) {
x = _x;
return foo;
}
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
})();
Even this is also a self executing function, but while execution it creates x variable and returns function foo, and foo access x by closure.
You are creating this type of holder just by normal function call object: createHolderB(0).
Both cases are really bad in practice.
If you're making closures (anonymous functions) that hold your "private variable" scope, it means you're creating those functions for every instance of the class. That costs memory and performance. I used to create classes like this, but then once I was making large number of instances and found out that it hits performance hard.
Just as in Python, make private variables private by some convention, like underscore in _name. Then you can break it for debug reasons (because variables in closure scope are not accessible).
This is how I would do it:
function MyClass(arg) {
this._privateVar = arg;
}
MyClass.prototype.getPrivateVar = function() {
return this._privateVar;
}
You can also make getters and setters:
Object.defineProperty(MyClass.prototype, "privateVar", {
get: function() {
return this._privateVar;
}
}
But don't try to push javascript into things it's not designed to, or you'll pay with performance, code readability and debugging complexity. Applies to other languages too.
var object = {}; //lots of stuff in here
var func = object.dosome;
object.dosome = function(a,b) {
func(a,b);
//someth else here i need to add
}
This works but ugly.
So is there a way to supplement object.dosome method, without creating a new variable containing it's function?
Some sort of parent.dosome?
maybe create a class Object and define in its protoype the dosome() method.
var Object = new function() {}; //lots of stuff in here
Object.prototype.dosome = function(a,b) {
func(a,b);
}
//and then
var myObject = new Object();
I think you should read a little about JS OOP. ES6 adds some nice syntactic sugar that can help you achieve what you want in fewer lines of code. Read more here.
However, if you don't want to have problems with the prototype chains, here's a simpler way of achieving what you want:
function chain (baseFunc, func) {
return function () {
var args = [].slice.call(arguments, 0);
args.unshift(baseFunc);
return func.apply(this, args);
};
}
Usage:
var obj = {
doSome: function (a, b) { return a + b; }
};
obj.doSome(4, 5); // 9
obj.doSome = chain(obj.doSome, function (baseFunc, a, b) {
var result = baseFunc(a, b);
return result + 10;
});
obj.doSome(4, 5); // 19
You can go one step further and get rid of the assignment:
function extend (instance, method, func) {
instance[method] = chain(instance[method], func);
}
extend(obj, "doSome", function (baseFunc, a, b) {
var result = baseFunc(a, b);
return result + 2;
});
obj.doSome(4, 5); // 21
I have some Javascript code spread over multiples files, yet I want to facilitate minification with an IFFE. Some methods must remain public.
Wikipedia suggests the implementation of accessors:
var counter = (function(){
var i = 0;
return {
get: function(){
return i;
},
set: function( val ){
i = val;
},
increment: function() {
return ++i;
}
};
}());
Unfortunately, declaring these from return is not easy when such functions are declared in multiple files.
Is the following a proper solution? If not, what is?
var counter = (function(){
var i = 0;
// Import js file 1...
this.get = function(){ return i; };
// Import js file 2...
this.set = function( val ){ i = val; };
// Import js file 3...
this.increment = function() { return ++i; };
return this;
}());
P.S.: I want to be able to perform the following calls:
counter.get();
counter.set(33);
counter.increment();
It seems like the pattern that you are interested in is something like this:
//file 1
var xy = (function (that) {
that.prop1 = 1;
return that;
}(xy || {}));
//file2
var xy = (function (that) {
that.prop2 = 2;
return that;
}(xy || {}));
This will result in a single global object xy that has two properties:
xy = {
prop1: 1,
prop2: 2
};