I am passing a function as an argument to a constructor within an IIFE. I realize that the outer function of an IIFE is going to be executed, but it appears the function argument is also executed. I don't really understand why and am wondering how to work around this problem. Here are two examples:
var Foo = function(bar) {
this.bar = bar;
};
new Foo(function() { console.log("test"); });
In the above example, things work as I'd expect. The anonymous function is passed as an argument to the Foo constructor, but is not run.
Here's another example, where it appears an anonymous function that is created within an IIFE is executed, even though it is not explicitly called:
(function() {
var Foo = function(bar) {
this.bar = bar;
};
Foo.STATIC_FIELD = new Foo(new function() { console.log("test"); });
return Foo;
})();
In this second example, "test" is written to the console. I am using the IIFE to protect the global name space from polluting it with Foo. However, I do not want the function passed to the Foo constructor to be immediately executed. It's a function I'm holding onto so that it can be later invoked with Foo.STATIC_FIELD.bar(); What's the best way to achieve this?
My question was answered sufficiently in the comments by Mike C and DavidS. If you want to store a function for later invocation, don't use "new" because that will run the function. Later, be sure to call "call" on that function with the context of the object holding onto the function. For example:
foo.myFunction.call(foo);
Related
What is the difference between these two?
I import both in browserify and they seem to give the same result.
Is there any difference between them and how they work?
var App = (function () {
var Foo = function (name) {
this.name = name;
};
Foo.prototype.logout = function () {
console.log();
}
return Foo;
})();
module.exports = App;
VS
var Foo = function (name) {
this.name = name;
};
Foo.prototype.logout = function () {
console.log();
}
module.exports = Foo;
In this particular case, the only difference is that in the first code sample you end up with a variable named "App", and in the second you end up with one named "Foo". Other than that effect on the namespace, the two do the same thing.
More generally, code that looks like this:
var x = function() {
// lots of stuff
return something;
}();
allows for "lots of stuff" to be done in a context that's isolated from the surrounding context. That means that functions and variables defined inside that anonymous function won't "leak out" into the surrounding context unless that's an explicit goal of the return statement (or other code that otherwise affects some outer context somehow, most typically by direct modifications to window or something like the jQuery prototype).
In your example, again, the "lots of stuff" in the second example didn't involve altering any namespace other than that function prototype, which the first code does too.
Yes, there is difference between these two. First example keeps you safe from polluting your global scope with Foo variable, since it's wrapped in IFEE(Immediately Invoked Function Expressions) and assigned to variable App. Since Foo is inside IFEE it belongs to IFEE's scope.
Foo variable from second example is in global scope and if you import this file in some other code Foo would override variable from that file if there also exist variable with that name. So to be sure that this wouldn't happen it's better to wrap imported code into IFEE.
Also, accessing variable Foo is different, in first example you would access it with App.Foo (since it's namespaced under App) and in second you access it with Foo.
I am trying to understand how IIFE in JS works.
I first ran this:
(function boo() {
var i = 90;
console.log(i);
})();
and adding below
boo();
doesn't run.
Q1: Why? is this named iife not stored for reference to be called later on?
When I do this
var tee = function boo() {
var i = 90;
console.log(i);
};
tee();
boo();
it runs
but when I do this
var tee = function boo() {
var i = 90;
console.log(i);
};
boo();
tee();
It doesn't run.
Q2: Why?
Q1: Why? is this named iife not stored for reference to be called later on?
Basically yes. The name of a function expression does not become a symbol in the enclosing scope. E.g. if you have
var foo = function bar() {
// `bar` is defined here, `foo === bar`
};
// only `foo` is defined here
then you can only access foo. bar is only accessibly within the function (and refers to the function itself). See Named function expressions demystified for more info.
Q2
This has nothing to do with IIFE. Both of them are actually broken.
The reason why you don't see an output in the second example is because you are trying to access boo (which does not exist) before calling tee (which does exist).
JavaScript stops executing the code when it throws an error, hence tee is never called.
Unfortunately .bind has been giving me grief when creating more complex closures.
I am quite interested in why .bind seems to work differently once you nest functions.
For example :
function t(){
t = t.bind({}); //correctly assigns *this* to t
function nested_t(){
nested_t = nested_t.bind({}); // fails to assign *this* to nested_t
return nested_t;
}
return nested_t();
}
//CASE ONE
alert(t());
// alerts the whole function t instead of nested_t
//CASE TWO
aleft(t.call(t));
// alerts the global object (window)
In both cases I was expecting a behavior like this:
function t(){
var nested_t = function nested_t(){
return this;
};
return nested_t.call(nested_t);
}
alert(t.call(t));
If someone could explain the behavior of .bind in the first (and/or) second case it would be much appreciated!
So, i'm not entirely reproducing your issue here (both cases return the global object), but i'll try and explain the code as i see it.
function t(){
t = t.bind({}); //correctly assigns *this* to t
function nested_t(){
nested_t = nested_t.bind({}); // fails to assign *this* to nested_t
return this;
}
return nested_t();
}
//CASE ONE
alert(t());
Let's take it step by step.
First, the function t() is defined. Then, upon call, it gets overwritten with a clean context. However, i don't see any usage of this context.
Now, a nested function (nested_t) is defined. Upon call, it is overwritten with a clean context. It then returns the context it had when it was called.
Back to t(). You then return the result of nested_t(), not nested_t itself. In the original function call, nested_t is still being called with global context.
Therefore, when you run t(), it returns the global object.
How your code works
It's very unclear, what your code is trying to do. You can find the documentation for .bind() here. It looks like you might be somehow misunderstanding what this is and how to use it. Anyway, what happens when you run your code is this:
A t function is created in global scope.
[case one] The t function is called.
Global scope t is replaced with a new value (original t bound to a specific context - anonymous empty object), which doesn't affect the current call in any way. Also, while the global t is overwritten, the local t is behaving as read-only. You can check it out by trying the following code: (function foo () { return (function bar () { bar = window.bar = 'baz'; return bar; })(); })() and comparing return value with window.bar.
The same thing happens with nested_t in the nested context (instead of global context).
Result of nested_t call is returned. nested_t returns the context it was called with, which was window, as no context was specified. Specifically, it was not called with an empty object context, because the .bind() inside didn't affect the call itself.
[case two] The exact same thing happens once again. Now you're just calling t with itself as context. Since t doesn't use its context (this) anywhere in its code, nothing really changes.
What your misconceptions might be
Basically, you're mixing up two things - function instance and function call context. A function is a "first-class citizen" in JavaScript - it's an object and you can assign values to its properties.
function foo () {
foo.property = 'value';
}
foo(); // foo.property is assigned a value
This has nothing to do with function call context. When you call a function a context is assigned to that call, which can be accessed using this (inside function body)
function foo () {
this.property = 'value';
}
var object = {};
foo.call(object); // object.property is assigned a value
When you use .bind(), you just create a new function with the same code, that is locked to a specific context.
function foo () {
this.property = 'value';
}
var fixedContext = {},
object = {};
bar = foo.bind(fixedContext);
foo.call(object); // fixedContext.property is set instead of object.property
But in this case, there are also function instances foo and bar, which can also be assigned properties, and which have nothing to do with contexts of calls of those functions.
Let's look at how bind works. First, one level of nesting:
var foo = function() { return this.x; };
alert(foo()); // undefined
alert(foo.bind({x: 42})()); // 42
Now we can add the next level of nesting:
var bar = function() { return foo.bind(this)(); };
alert(bar()); // undefined
alert(bar.bind({x: 42})());
We pass our this context to foo with - guess what? - bind. There is nothing different about the way bind works between scopes. The only difference is that we've already bound this within bar, and so the body of bar is free to re-bind this within foo.
As a couple of commenters have noted, functions that overwrite themselves are a huge code smell. There is no reason to do this; you can bind context to your functions when you call them.
I highly, highly recommend reading the documentation on bind, and trying to understand it to the point where you can write a basic version of Function.prototype.bind from scratch.
So the have seem something like this today:
$$('input').each(function() {
// do something
});
What is the difference between that and this:
$$('input').each( // do something );
The private function on the first example is within that for loop scope, so it is not reference-able anywhere else, so what would the benefit of having it?
The anonymous function knows its current scope and variables.
function a() {
var foo = 'test';
$('something').each(function() {
alert(foo);
})
}
This function would alert 'test' because foo is defined within its scope.
function a() {
var foo = 'test';
$('something').each(b)
}
function b() {
alert(foo);
}
This function would cause a javascript error stating that the variable foo is undefined.
If you need to define a function that only makes sense within an exact scope and don't want to throw lots of variables around or recalculate a lot of things, it's more comfortable to define an anonymous function.
This is not private function, it's just an anonymous function (function without name).
You could do:
$('input').each(function() {
// do something
});
Or you could do:
function foo() {
// do something
}
$('input').each(foo);
Anyway, the .each method needs a function to be the parameter which is a callback.
The first function is not private. It can reference all variables in the containing scope to form a closure, because JavaScript has lexical scoping.
The second function is pretty much the same thing, except the only thing you can do is provide it with a function name, or you will get a syntax error.
Short Answer: You put the function statement there to do more than one thing, or do one thing and provide parameters.
I'm a little confused.
Everywhere i look, people say that i should use self invoking functions for scoping reasons, to avoid global namespace pollution.
But in this aspect, self invoking function seems to act identically to regular function, as in this example:
function xx(){
var x="variable";
//logs into console
console.log(x);
}
xx();
//logs undefined
console.log(x);
So, only real difference with regular function and self invoking is "self invoking" part, meaning i just don't have to run function manually after declaration?
A “self-invoking function” is a name for a common JavaScript idiom. It’s not actually a type of function; it’s the immediate execution of a function. You can call it an IIFE for “immediately invoked function expression” instead if that helps.
(function () { // Anonymous function expression
// IIFE!
})(); // Invocation happens here with the ()!
var f = (function () { // Still anonymous
// Almost immediately invoked function expression!
});
f(); // Invocation happens here!
var f = (function f() { // Not anonymous – now called “f”
// Almost immediately invoked function expression!
});
f(); // Invocation happens here!
function f() { // Not anonymous
// Almost immediately invoked function *declaration* – not an expression!
}
f(); // Invocation happens here!
Self-invoking functions are normal functions, but don't have a name. That makes them impossible to call except immediately after being declared, which effectively makes them a one-time-use function that is forever hidden from other code.
As you point out, the form
function foo() {
console.log("foo");
}
foo()
and
(function () {
console.log("foo");
})()
behave identically.
However, the first form with function foo() {... creates a named function that lives in that scope until the scope is destroyed. For the global scope, that will never happen, leaving foo a valid and callable identifier for any other code in your application.
That means that at any time, anybody else can do
foo()
and either initialize your module again or, potentially, obtain a handle to a new copy of the module.
At best, this can cause confusion and duplicate state. At worst, depending on how your IIFE is structured, they may be able to dig into hidden state and start manipulating it in ways you don't expect.
Writing a function that is both anonymous and immediately invoked prevents anyone from ever invoking it again, making it a clean and safe way to create and use a completely hidden scope. That's why you see it used so often to provide private state or construct a module.
They must have confused a IIFE with "self-invoking function".
Here's something Ben Alman wrote:
What’s wrong with “Self-executing anonymous function?”
You’ve already seen it mentioned a few times, but in case it wasn’t clear, I’m proposing the term “Immediately-Invoked Function Expression”, and “IIFE” if you like acronyms. The pronunciation “iffy” was suggested to me, and I like it, so let’s go with that.
What is an Immediately-Invoked Function Expression? It’s a function expression that gets invoked immediately. Just like the name would lead you to believe.
I’d like to see JavaScript community members adopt the term “Immediately-Invoked Function Expression” and “IIFE” in their articles and presentations, because I feel it makes understanding this concept a little easier, and because the term “self-executing anonymous function” isn’t really even accurate:
// This is a self-executing function. It's a function that executes (or
// invokes) itself, recursively:
function foo() { foo(); }
// This is a self-executing anonymous function. Because it has no
// identifier, it must use the the `arguments.callee` property (which
// specifies the currently executing function) to execute itself.
var foo = function() { arguments.callee(); };
// This *might* be a self-executing anonymous function, but only while the
// `foo` identifier actually references it. If you were to change `foo` to
// something else, you'd have a "used-to-self-execute" anonymous function.
var foo = function() { foo(); };
// Some people call this a "self-executing anonymous function" even though
// it's not self-executing, because it doesn't invoke itself. It is
// immediately invoked, however.
(function(){ /* code */ }());
// Adding an identifier to a function expression (thus creating a named
// function expression) can be extremely helpful when debugging. Once named,
// however, the function is no longer anonymous.
(function foo(){ /* code */ }());
// IIFEs can also be self-executing, although this is, perhaps, not the most
// useful pattern.
(function(){ arguments.callee(); }());
(function foo(){ foo(); }());
// One last thing to note: this will cause an error in BlackBerry 5, because
// inside a named function expression, that name is undefined. Awesome, huh?
(function foo(){ foo(); }());
Source : http://benalman.com/news/2010/11/immediately-invoked-function-expression/
// defined at `window`
function xx() {
var x = "variable";
//logs into console
console.log(x);
}
xx();
// not defined at `window`
(function yy() {
var y = "variable";
//logs into console
console.log("y:",y);
// `window["yy"]` : `undefined`
console.log("yy:", yy, "window['yy']:?", window["yy"]);
}());
console.log("xx", xx, window["xx"]);
try {
console.log("yy:", yy, window["yy"]);
} catch (e) {
console.log("yy:", e)
}
try {
console.log("x:", x);
} catch (e) {
console.log("x:", e)
}