Method chaining within a javascript closure module - javascript

Here's a question for js gurus. I'd like to enable method chaining in a js module coded as follows. I'd also like for each method to be able to return an object literal of various values. In the context of how this is coded, how would I enable the function chaining such as method2().method3()
Thanks!
var module1Constructor = (function() {
// methods:
var init = function() {
var someValue = 'value';
method2().method3(); // chained method calls
return {module1:'iDontKnow',returnedValue1:someValue}; // how to pass value back to enable function chaining?
}; // init
var method2 = function() {
var someValue = 'value';
return {module1:'iDontKnow',returnedValue1:someValue}; // how to pass value back to enable function chaining?
}; // method2
var method3 = function() {
var someValue = 'value';
return {module1:'iDontKnow',returnedValue1:someValue}; // how to pass value back to enable function chaining?
}; // method3
return function module1Constructor() {
this.init = init;
} // return function module1Constructor() {
})(); // module1Constructor
var module1 = new module1Constructor;
module1.init();

How is method chaining necessary if it isnt accessible by the user?
So you may want to write onto the prototype of a function, making it a regular constructor:
function module1Constructor(){
//...
}
module1Constructor.prototype={
test:1,
a:function(){
alert(this.test++);
return this;
},
//extended
b:function(){
return Object.assign(new module1Constructor(),this,{c:alert});
}
};
Use like this:
test=new module1Constructor().a().a().a().a();
test.a().c();//doesnt work
test.a().b().c();//does work
test.a().b().a();

The term method chaining is more related to prototypes, in this case, what I see in your comments is you want to access values within functions, that is called closure, which is a way to access a value when a function is invoked outside it's lexical scope. so in your object literal that you are returning, you can do.
var method2 = function() {
var someValue = 'value';
return {module1:'iDontKnow',returnedValue1:someValue, method3:method3};
}

Related

Unable to access the object using `this`. `this` points to `window` object

I have this Javascript constructor-
function TestEngine() {
this.id='Foo';
}
TestEngine.prototype.fooBar = function() {
this.id='bar';
return true;
}
TestEngine.prototype.start = function() {
this.fooBar();
}
TestEngine.prototype.startMethod = function() {
inter = setInterval(this.start, 200);
}
var test = new TestEngine();
test.startMethod();
Gives me this error -
Uncaught TypeError: Object [object global] has no method 'fooBar'
I tried console.log and found out that when I call this.start from within setInterval, this points to the window object. Why is this so?
The this pointer can point to one of many things depending upon the context:
In constructor functions (function calls preceded by new) this points to the newly created instance of the constructor.
When a function is called as a method of an object (e.g. obj.funct()) then the this pointer inside the function points to the object.
You can explicitly set what this points to by using call, apply or bind.
If none of the above then the this pointer points to the global object by default. In browsers this is the window object.
In your case you're calling this.start inside setInterval. Now consider this dummy implementation of setInterval:
function setInterval(funct, delay) {
// native code
}
It's important to understand that start is not being called as this.start. It's being called as funct. It's like doing something like this:
var funct = this.start;
funct();
Now both these functions would normally execute the same, but there's one tiny problem - the this pointer points to the global object in the second case while it points to the current this in the first.
An important distinction to make is that we're talking about the this pointer inside start. Consider:
this.start(); // this inside start points to this
var funct = this.start;
funct(); // this inside funct (start) point to window
This is not a bug. This is the way JavaScript works. When you call a function as a method of an object (see my second point above) the this pointer inside the function points to that object.
In the second case since funct is not being called as a method of an object the fourth rule is applied by default. Hence this points to window.
You can solve this problem by binding start to the current this pointer and then passing it to setInterval as follows:
setInterval(this.start.bind(this), 200);
That's it. Hope this explanation helped you understand a little bit more about the awesomeness of JavaScript.
Here is a neat way to do OOP with javascript:
//Global Namespace:
var MyNamespace = MyNamespace || {};
//Classes:
MyNamespace.MyObject = function () {
this.PublicVar = 'public'; //Public variable
var _privatVar = 'private'; //Private variable
//Public methods:
this.PublicMethod = function () {
}
//Private methods:
function PrivateMethod() {
}
}
//USAGE EXAMPLE:
var myObj = new MyNamespace.MyObject();
myObj.PublicMethod();
This way you encapsulate your methods and variables into a namespace/class to make it much easier use and maintain.
Therefore you could write your code like this:
var MyNamespace = MyNamespace || {};
//Class: TestEngine
MyNamespace.TestEngine = function () {
this.ID = null;
var _inter = null;
//Public methods:
this.StartMethod = function (id) {
this.ID = id;
_inter = setInterval(Start, 1000);
}
//Private methods:
function Start() {
FooBar();
console.log(this.ID);
}
function FooBar() {
this.ID = 'bar';
return true;
}
}
//USAGE EXAMPLE:
var testEngine = new MyNamespace.TestEngine();
testEngine.StartMethod('Foo');
console.log(testEngine.ID);
Initially, the ID is set to 'Foo'
After 1 second the ID is set to 'bar'
Notice all variables and methods are encapsulated inside the TestEngine class.
Try this:
function TestEngine() {
this.id='Foo';
}
TestEngine.prototype.fooBar = function() {
this.id='bar';
return true;
}
TestEngine.prototype.start = function() {
this.fooBar();
}
TestEngine.prototype.startMethod = function() {
var self = this;
var inter = setInterval(function() {
self.start();
}, 200);
}
var test = new TestEngine();
test.startMethod();
setInterval calls start function with window context. It means when start gets executed, this inside start function points to window object. And window object don't have any method called fooBar & you get the error.
Anonymous function approach:
It is a good practice to pass anonymous function to setInterval and call your function from it. This will be useful if your function makes use of this.
What I did is, created a temp variable self & assigned this to it when it is pointing your TestEngine instance & calling self.start() function with it.
Now inside start function, this will be pointing to your testInstance & everything will work as expected.
Bind approach:
Bind will make your life easier & also increase readability of your code.
TestEngine.prototype.startMethod = function() {
setInterval(this.start.bind(this), 200);
}

Javascript module pattern, scope and "this"

I'm trying to wrap my head around building a custom JavaScript library. I've read a lot about the module pattern, and also read Crockford's articles on private and public members. I know what is an immediately invoked function expression and why we do stuff like
var myLib = (function() {
}())
However, I'm still a little lost in some cases regarding scope and closures in general. The concrete problem I have is:
Why does the following example alert DOMWindow, rather than the myLib object?
http://jsfiddle.net/slavo/xNJtW/1/
It would be great if you can explain what "this" refers to in all of the methods in that example and why.
Inside any function declared (anywhere) and invoked as follows this will be window object
function anyFunc(){
alert(this); // window object
}
anyFunc();
var anyFunc2 = function(){
alert(this); // window object
}
anyFunc2();
If you want to create private functions and access the instance of 'myObject' you can follow either of the following methods
One
module = (function () {
var privateFunc = function() {
alert(this);
}
var myObject = {
publicMethod: function() {
privateFunc.apply(this); // or privateFunc.call(this);
}
};
return myObject;
}());
module.publicMethod();
Two
module = (function () {
var _this; // proxy variable for instance
var privateFunc = function() {
alert(_this);
}
var myObject = {
publicMethod: function() {
privateFunc();
}
};
_this = myObject;
return myObject;
}());
module.publicMethod();
These are solutions to your issue. I would recommend using prototype based objects.
EDIT:
You can use the first method.
In fact here myObject is in the same scope as privateFunc and you can directly use it inside the function
var privateFunc = function() {
alert(myObject);
}
The real scenario were you can use a proxy for this is shown below. You can use call also.
Module = function () {
var _this; // proxy variable for instance
var privateFunc = function() {
alert(this + "," + _this);
}
this.publicMethod = function() {
privateFunc(); // alerts [object Window],[object Object]
privateFunc.call(this); // alerts [object Object],[object Object]
}
_this = this;
return this;
};
var module = new Module();
module.publicMethod();
You need to explicitly state that myPrivateMethod is a member of myLib:
function MyLib ()
{
this._myPrivateField = "private";
this._myPrivateMEthod = function ()
{
alert(this); // Alerts MyLib function;
}
}
var libObject = new MyLib();
Just remember that without using enclosure techniques, nothing in JavaScript is ever truly private!
A better way to do the above is like so:
function MyLib(instanceName)
{
this.name = instanceName;
}
MyLib.prototype.myPrivateFunction()
{
alert(this);
}
To call your method after that:
var libObject = new MyLib();
libObject.myPrivateMethod(); // Alerts info about libObject.
The thing to remember about the module pattern is that it runs once and completes. The methods that are still available to be called are the closures. At the time of creating module, "this" refered to the window and was replaced by its value.
In your linked fiddle, the "this" keyword is never changed by a "new" keyword or other context change, so it still refers to the global window object.
edit: clarification

Is this proper javascript for making a namespace that encapsulates various methods into different objects?

var namespaced = {
A: function(){
function r(){
//do some stuff
return something;
}
var someProperty = 5;
function j(){
//do some more stuff
return something;
}
},
B: function(){
//can I call A and C?
A.r();
C.d();
},
C: function(){
function d() {
//do stuff we like
}
}
}
Then I could do...
namespaced.A.j();
namespaced.C.d();
something = namespaced.A.someProperty;
right?
Would I need to do this too?
var something = new namespaced.A()?
If so does A() have a constructor? I'm really confused here :{
I'm trying to encapsulate my javascript so it's easy to maintain
Then I could do...
namespaced.A.j();
namespaced.C.d();
something = namespaced.A.someProperty;
No you couldn't. The function j and someProperty are only local to A and are not propagated to the outside. If you want to access them from the outside, you have to make them a property of the function, using this:
var namespaced = {
A: function(){
this.r = function(){
//do some stuff
return something;
};
this.someProperty = 5;
this.j = function(){
//do some more stuff
return something;
};
}
}
But you would still need to call var a = new namespaced.A() in order to access the functions.
If you want to call namespaced.A.j() directly, you would have to declare A as object, not as function:
var namespaced = {
A: {
r: function(){
//do some stuff
return something;
},
someProperty: 5,
j: function(){
//do some more stuff
return something;
}
}
}
So it depends on what you want to achieve eventually... to get a better insight into these methods, I recommend JavaScript Patterns.
This is what you need to understand about JavaScript:
When you write
var obj = { A: a, B: b, C: c };
you are creating (and assigning to obj) an object with properties called A, B and C mapping to values a, b and c respectively. These values may very well be functions, so when you have
var obj = { A: function(){...} };
you are creating an object with a property called "A" which is a function. You can refer to it with obj.A and call with obj.A().
When you call obj.A(), the keyword this inside the body of function A will refer to obj. You can use it to assign new properties to obj:
var obj = {
A: function() { this.prop = "Hello!"; }
};
obj.A();
alert( obj.prop ); // alerts "Hello!"
So, inside namespaced.A.j() the this keyword will point to namespace.A (it's what is to the left of the last dot).
You can apply a function to an object like so: func.apply(obj) or like so: func.call(obj). In this case, the this keyword will refer to obj instead. This isn't relevant to your case, but if func takes parameters (let's say param1 and param2), you can apply the function like so: func.apply(obj, [val1, val2]) or like so: func.call(obj, val1, val2).
All variables declared inside a function live only inside that function. They are not visible outside. And when you write function doStuff(){} it's (I'm simplifying here) as good as if you wrote var doStuff = function(){}; So nested functions live and can be used only inside the surrounding function; that is, unless you assign them to something accessible from outside.
When you call something like new Cons() what happens is the creation of a new empty object followed by the application of Cons() on that object. In other words, it's the same as
var obj = {};
Cons.apply(obj);
or if you prefer:
var obj = {};
obj.Cons = Cons;
obj.Cons();
// obj's Cons property then mysteriously disappears
// unless it was explicitly set inside Cons() (oh my, how confusing! :)
So you can have this:
function Duck(name){
this.myName = name;
this.quack = function(){
alert(this.myName + " quacks!");
}
};
donald = new Duck('Donald');
donald.quack();
With all the preceding in mind, a way to write namespaced code is like this:
// The following syntax, confusing to someone who hasn't seen it before,
// is defining a new anonymous function and immediately using it
// as a constructor applied to a new empty object.
//
// Alternatively, you can use this syntax:
// var namespaced = {};
// (function(){
// ....
// }).apply(namespaced);
//
var namespaced = new (function(){
// This creates a new variable named "namespaced"
// which is visible only inside this anonymous function.
// This variable points to the still-empty object created by
// 'new'. This object will, once we're done with this anonymous function,
// be assigned to a variable, outside, which by "coincidence" is
// also named "namespaced".
var namespaced = this;
// You could alternatively not create the variable "namespaced"
// and use 'this' directly inside this anonymous function. But,
// the 'this' keyword may point to different objects inside the
// nested functions that follow, so we create it to avoid confusion.
// This assigns a new object to variable 'A', which isn't visible outside.
// Use a constructor function defined inline.
var A = new (function(){
var A = this; // 'this' now refers to the empty object created just above
this.someProperty = 5; // Two different ways of
A.anotherProperty = 7; // doing mostly the same thing
this.j = function(){
//do some more stuff
// 'this' will point to j, here
return something;
}
// Function r isn't visible outside of A's constructor like this!
function r(){
//do some stuff
return something;
}
// Make 'r' visible outside by assigning it to a property of 'A'.
// Look, it's also called "r". What fun!
A.r = r;
})();
// Make the object in variable 'A' visible outside of
// 'namespaced's constructor, by making it a property of 'namespaced'
namespaced.A = A;
// Create a new object as before.
// This time we won't make it visible outside
// of "namespaced"'s constructor.
var C = new (function(){
this.d = function (){
//do stuff we like
}
})();
// Give "namespaced" a property 'B'.
// This time it's a function instead of a nested object.
namespaced.B = function(){
// It's cool to make these function calls here, because
// (a) nested functions can see the variables ('A' & 'C')
// of surrounding functions, even if they terminate in the meantime;
// and (b) 'r' & 'd' are properties of 'A' and 'C'.
A.r();
C.d();
};
// You could return 'this' or 'namespaced' from this constructor,
// but the 'new' keyword will make sure the "namespaced" variable
// outside will get the no-longer-empty object it created,
// so you can just not return anything.
})();
// Now you can do
five = namespaced.A.someProperty;
seven = namespaced.A.anotherProperty;
something = namespaced.A.j();
namespaced.B(); // Calls A.r() and C.d()
// But you can't do
namespaced.C.d(); // WRONG: "namespaced" doesn't have a property named "C"
I hope this helps more than it confuses.

javascript - shortcut for calling a function at the same time it is defined

to call a function at the same time it's defined, i had been using:
var newfunc = function() {
alert('hi');
};
newfunc();
is the following the correct way of combining these 2:
var newfunc = function() {
alert('hi');
}();
There could be a number of reasons you wish to do this. I'm not sure what yours are, but let me introduce a couple of favourite patterns:
Pattern #1: A singleton. The function is executed and then becomes a singleton object for use by other components of your code.
var singletonObject = new function() {
// example private variables and functions
var variable1 = {};
var variable2 = {};
var privateFunction = function() {
};
// example public functions
this.getData = function() {
return privateFunction(variable1, variable2);
};
// example initialisation code that will only run once
variable1.isInitialised = true;
};
Pattern #2: Self-executing anonymous function ... handy for sooo many reasons!
// Declare an anonymous function body.
// Wrap it in parenthesis to make it an "expression.
// Execute it by adding "();"
(function(){})();
And here's an example that also creates a namespace for your objects.
I'm using "NS" as an example namespace:
// declare the anonymous function, this time passing in some parameters
(function($, NS) {
// do whatever you like here
// execute the function, passing in the required parameters.
// note that the "NS" namespace is created if it doesn't already exist
})(jQuery, (window.NS = window.NS || {}));
You can also set the context of a self-executing function by using .call or .apply instead of the usual parenthesis, like this:
(function($){
// 'this' now refers to the window.NS object
}).call(window.NS = window.NS || {}, jQuery);
or
(function($){
// 'this' now refers to the window.NS object
}).apply(window.NS = window.NS || {}, [jQuery]);
var newfunc = function f() {
alert("hi!");
return f;
}();
Having a named function expressions allows the function to recursively call itself or, in this case, return itself. This function will always return itself, however, which might be an annoyance.
No. Your second example will immediately call the anonymous function and assign its return value to newfunc.
adamse describes an approach which appears to work. I'd still avoid the approach as the two step process is easier to read and thus will be easier to maintain.
If I understand your question correctly, give this a try:
(f = function (msg) {
msg = msg ? msg : 'default value';
alert(msg); }
)();
f('I\'m not the default value!');
You'll get two alerts, the first one will say "default value" and the second will say "I'm not the default value. You can see it in action at jsBin. Click 'preview' to make it run.
you could do like this:
o = {};
o.newfunc = ( function() {
function f() {
alert('hi');
}
f();
return {
f : f
};
}
)();
then calling the function like:
o.newfunc.f();
will also render an alert message

javascript singleton question

I just read a few threads on the discussion of singleton design in javascript. I'm 100% new to the Design Pattern stuff but as I see since a Singleton by definition won't have the need to be instantiated, conceptually if it's not to be instantiated, in my opinion it doesn't have to be treated like conventional objects which are created from a blueprint(classes). So my wonder is why not just think of a singleton just as something statically available that is wrapped in some sort of scope and that should be all.
From the threads I saw, most of them make a singleton though traditional javascript
new function(){}
followed by making a pseudo constructor.
Well I just think an object literal is enough enough:
var singleton = {
dothis: function(){},
dothat: function(){}
}
right? Or anybody got better insights?
[update] : Again my point is why don't people just use a simpler way to make singletons in javascript as I showed in the second snippet, if there's an absolute reason please tell me. I'm usually afraid of this kind of situation that I simplify things to much :D
I agree with you, the simplest way is to use a object literal, but if you want private members, you could implement taking advantage of closures:
var myInstance = (function() {
var privateVar;
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// private members can be accessed here
},
publicMethod2: function () {
// ...
}
};
})();
About the new function(){} construct, it will simply use an anonymous function as a constructor function, the context inside that function will be a new object that will be returned.
Edit: In response to the #J5's comment, that is simple to do, actually I think that this can be a nice example for using a Lazy Function Definition pattern:
function singleton() {
var instance = (function() {
var privateVar;
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// private members can be accessed here
},
publicMethod2: function () {
// ...
}
};
})();
singleton = function () { // re-define the function for subsequent calls
return instance;
};
return singleton(); // call the new function
}
When the function is called the first time, I make the object instance, and reassign singleton to a new function which has that object instance in it's closure.
Before the end of the first time call I execute the re-defined singleton function that will return the created instance.
Following calls to the singleton function will simply return the instance that is stored in it's closure, because the new function is the one that will be executed.
You can prove that by comparing the object returned:
singleton() == singleton(); // true
The == operator for objects will return true only if the object reference of both operands is the same, it will return false even if the objects are identical but they are two different instances:
({}) == ({}); // false
new Object() == new Object(); // false
I have used the second version (var singleton = {};) for everything from Firefox extensions to websites, and it works really well. One good idea is to not define things inside the curly brackets, but outside it using the name of the object, like so:
var singleton = {};
singleton.dothis = function(){
};
singleton.someVariable = 5;
The ES5 spec lets us use Object.create():
var SingletonClass = (function() {
var instance;
function SingletonClass() {
if (instance == null) {
instance = Object.create(SingletonClass.prototype);
}
return instance;
}
return {
getInstance: function() {
return new SingletonClass();
}
};
})();
var x = SingletonClass.getInstance();
var y = SingletonClass.getInstance();
var z = new x.constructor();
This is nice, since we don't have to worry about our constructor leaking, we still always end up with the same instance.
This structure also has the advantage that our Singleton doesn't construct itself until it is required. Additionally, using the closure as we do here prevents external code from using our "instance" variable, accidentally or otherwise. We can build more private variables in the same place and we can define anything we care to export publically on our class prototype.
The singleton pattern is implemented by creating a class with a method that creates a new instance of the class if one does not exist. If an instance already exists, it simply returns a reference to that object. 1
(function (global) {
var singleton;
function Singleton () {
// singleton does have a constructor that should only be used once
this.foo = "bar";
delete Singleton; // disappear the constructor if you want
}
global.singleton = function () {
return singleton || (singleton = new Singleton());
};
})(window);
var s = singleton();
console.log(s.foo);
var y = singleton();
y.foo = "foo";
console.log(s.foo);
You don't just declare the singleton as an object because that instantiates it, it doesn't declare it. It also doesn't provide a mechanism for code that doesn't know about a previous reference to the singleton to retrieve it. The singleton is not the object/class that is returned by the singleton, it's a structure. This is similar to how closured variables are not closures, the function scope providing the closure is the closure.
I am just posting this answer for people who are looking for a reliable source.
according to patterns.dev by Lydia Hallie, Addy Osmani
Singletons are actually considered an anti-pattern, and can (or.. should) be avoided in JavaScript.
In many programming languages, such as Java or C++, it's not possible to directly create objects the way we can in JavaScript. In those object-oriented programming languages, we need to create a class, which creates an object. That created object has the value of the instance of the class, just like the value of instance in the JavaScript example.
Since we can directly create objects in JavaScript, we can simply use
a regular object to achieve the exact same result.
I've wondered about this too, but just defining an object with functions in it seems reasonable to me. No sense creating a constructor that nobody's ever supposed to call, to create an object with no prototype, when you can just define the object directly.
On the other hand, if you want your singleton to be an instance of some existing "class" -- that is, you want it to have some other object as its prototype -- then you do need to use a constructor function, so that you can set its prototype property before calling it.
The latter code box shows what I've seen JS devs call their version of OO design in Javascript.
Singetons are meant to be singular objects that can't be constructed (except, I suppose, in the initial definition. You have one, global instance of a singleton.
The point of using the "pseudo constructor" is that it creates a new variable scope. You can declare local variables inside the function that are available inside any nested functions but not from the global scope.
There are actually two ways of doing it. You can call the function with new like in your example, or just call the function directly. There are slight differences in how you would write the code, but they are essentially equivalent.
Your second example could be written like this:
var singleton = new function () {
var privateVariable = 42; // This can be accessed by dothis and dothat
this.dothis = function () {
return privateVariable;
};
this.dothat = function () {};
}; // Parentheses are allowed, but not necessary unless you are passing parameters
or
var singleton = (function () {
var privateVariable = 42; // This can be accessed by dothis and dothat
return {
dothis: function () {
return privateVariable;
},
dothat: function () {}
};
})(); // Parentheses are required here since we are calling the function
You could also pass arguments to either function (you would need to add parentheses to the first example).
Crockford (seems to) agree that the object literal is all you need for a singleton in JavaScript:
http://webcache.googleusercontent.com/search?q=cache:-j5RwC92YU8J:www.crockford.com/codecamp/The%2520Good%2520Parts%2520ppt/5%2520functional.ppt+singleton+site:www.crockford.com&cd=1&hl=en&ct=clnk
How about this:
function Singleton() {
// ---------------
// Singleton part.
// ---------------
var _className = null;
var _globalScope = null;
if ( !(this instanceof arguments.callee) ) {
throw new Error("Constructor called as a function.");
}
if ( !(_className = arguments.callee.name) ) {
throw new Error("Unable to determine class name.")
}
_globalScope = (function(){return this;}).call(null);
if ( !_globalScope.singletons ) {
_globalScope.singletons = [];
}
if ( _globalScope.singletons[_className] ) {
return _globalScope.singletons[_className];
} else {
_globalScope.singletons[_className] = this;
}
// ------------
// Normal part.
// ------------
var _x = null;
this.setx = function(val) {
_x = val;
}; // setx()
this.getx = function() {
return _x;
}; // getx()
function _init() {
_x = 0; // Whatever initialisation here.
} // _init()
_init();
} // Singleton()
var p = new Singleton;
var q = new Singleton;
p.setx(15);
q.getx(); // returns 15
I stole this from CMS / CMS' answer, and changed it so it can be invoked as:
MySingleton.getInstance().publicMethod1();
With the slight alternation:
var MySingleton = { // These two lines
getInstance: function() { // These two lines
var instance = (function() {
var privateVar;
function privateMethod () {
// ...
console.log( "b" );
}
return { // public interface
publicMethod1: function () {
// private members can be accessed here
console.log( "a" );
},
publicMethod2: function () {
// ...
privateMethod();
}
};
})();
singleton = function () { // re-define the function for subsequent calls
return instance;
};
return singleton(); // call the new function
}
}

Categories

Resources