In this example code:
(function(){
var obj = function() {
};
obj.prototype.hello = function(){
console.log('Hello World!');
};
})();
I see a lot of libraries doing this. Why is wrapping your code in an Immediately Invoked Function Expression (IIFE) a good practice? And how do I access this object outside, like jquery does?
Because if I do something like this:
var test = new obj();
The browser displays that obj is undefined.
To avoid polluting outer scope. You're sure no variables are going to "get out" of it.
But yes, you do need to export it. Either using window.obj = obj; from inside (to make it global) or return it :
var obj = (function() {
var obj = function() {};
obj.prototype.sayHello = function() {};
return obj;
})();
Related
Let's say I have an object:
obj = {func1: function(){return $(h1)};} // notice, there is no $ defined anywhere...
And somewhere else I have a line
jq = require('jQuery');
Now want to write a function or something, that takes object and a jQuery as an argument and binds it so that I can do something like this:
obj2 = myBind(obj, jq);
obj2.func1(); // works
obj = {func1: function(){return $(h1)};}
notice, there is no $ defined anywhere...
Then it's going to stay undefined, unless you create such a variable in any parent scope (like the global one).
You however cannot inject variables into scopes you don't "own", you cannot access the scope of the obj.func1 closure from the function reference - you need to put your code in that scope beforehand.
You might however use properties instead of variables, something like
var obj = {
func1: function() {
return this.$("h1");
}
};
// later:
obj.$ = require("jQuery");
obj.func1();
What #bergi said is correct. A different solution might also be to use Function.bind in one way or another:
var obj = {
func1: function() {
return this("h1");
}
};
obj.func1 = obj.func1.bind(require('jQuery'));
// later:
obj.func1();
I have an application that uses the v8 javascript engine, and within that I add functions to namespace objects that execute lines of code from the database. The contents of these functions need to not have this added before every function call. Following is some example code of my problem
var obj = {};
obj.method = function(a) { return a; }
obj.executor = function() { return method(5); }
obj.executor()
ReferenceError: method is not defined
var caller = function() { return method(5); }
caller.call(obj)
ReferenceError: method is not defined
As you can see, neither way allows me to call method without first adding this. Is there some way of executing a function so that it's context is set in such a way that this does not need to be added?
EDIT
This did work in a previous version of the v8 engine, but it seems the most recent one is not allowing it now.
"The client's write rules which are the strings loaded from the database, and it was a requirement (who knows why) that they only need to write the function names and the application sorts out the scoping."
If you're not running in strict mode, you can use a with statement.
var obj = {};
obj.method = function(a) { return a; };
obj.executor = function() {
with (this) {
return method(5);
}
};
obj.executor();
var caller = function() {
with (this) {
return method(5);
}
};
caller.call(obj);
Not saying this is a great solution, but it'll work if those are the requirements given.
I don't know your other requirements, but you can achieve this via a closure as well.
var obj = {};
(function() {
var method = obj.method = function(a) { return a; };
obj.executor = function() {
return method(5);
};
}();
obj.executor();
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
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
I've got a question about self invoking functions in javascript.
What I'm doing is something similar to the following
myNamespace = {}; //namespace for holding any objects/functions
//helpModule as an example
myNamespace.HelpModule = new (function(){
this.abc = '123';
//lots of other code in here...
})();
now I'm able to access properties of myNamespace.HelpModule like so:
alert(myNamespace.HelpModule.abc);
But for starters jsLint doesn't like that saying "Weird construction. Delete 'new'.",
And this page states that you shouldn't use Function Constructor, although in this case I'm not sure if its using the Function Constructor since its a self invoking function?
Anyway, it seems to work fine, and the reason I'm using it is to have "this" scope to the function instead of the global object (window). I could just defining it as an object literal or do something similar to
myNamespace.HelpModule = (function(){
var obj = {};
obj.abc = '123';
return obj;
}();
but neither of these seem as "elegant" to me.
I'm wondering if this is bad form/practice?
It is weird because the purpose of defining a constructor is to be able to reuse it to create many objects.
For your purpose, you can use this construct-
myNamespace.HelpModule = (function(){
//private stuff here
var a = 100;
return {
//public stuff here
b : 200,
something: function() {
return a + this.b;
}
};
})();