While investigating google plusone scripts, I've seen following syntax many times:
(0, _.Em)();
Assuming _.Em is a function the statement above would result in calling that function, that's pretty obvious. If, on the other hand, it would be undefined, wouldn't the result be the same as doing simply _.Em() ?
Can anyone shed a light on what's idea behind using such syntax?
Basically, this syntax allows to call _.Em() in the context of the window object instead of _.
Assuming you have this code:
Foo = function() {
this.foo = "foo";
};
Foo.prototype.Em = function() {
alert(this.foo);
};
var _ = new Foo();
Issuing _.Em() will result in Em() being called in the context of _. Inside the function, the this keyword will refer to _, so foo will be printed.
Issuing (0, _.Em)() decouples the method call from the object and performs the call in the global context. Inside the function, the this keyword will refer to window, so undefined will be printed, since window does not have a foo property.
You can test the difference between the two syntaxes in this fiddle.
Related
I found this browsing:
What is the difference between a function call and function reference?
After reading the answers there, I did't understand the definition and usage for function references and function calls. Then I searched a lot, but it is still unclear where to use what.
Could you help me understand this by pointing out the differences in concept and usage? I want to make this as a reference for future programers.
Take this for example:
function foo() {
alert('foo');
return 'bar';
}
First of all, what is a function? It's a routine that can be called (or "invoked", or "executed"), and when you do so it usually does something, and returns some value.
So you have a function named foo. You can call it by adding () after its name:
foo();
You can store the return value in a variable, if you assign the result of the invocation to it:
var something = foo();
something === 'bar'; // true
But that's not all you can do with functions in JavaScript. It's a language where functions are first class citizens, so they can be passed around to other functions, and returned from other functions. They can also be stored as variables. For example:
var refToFoo = foo;
Now refToFoo is the same as foo. It's not a copy, it's a reference pointing to the same (internal) function object as foo. So you can use refToFoo just like you would use foo:
var something = refToFoo();
something === 'bar'; // true
refToFoo === foo; // true; they're the same object
Perhaps the most common use to function references is to use them as event listeners:
someElement.onclick = foo;
Note there is no parentheses above. It we used parentheses, foo would be invoked, immediately, and its return value would be assigned to the element's onclick method. Since that function returns a string, nothing would happen if the element were clicked. That's a very common mistake newbies do. Another common one is invoking a function instead of passing a reference to setTimeout:
setTimeout(foo(), 1000); // WRONG - foo is executed immediately
Compare that to:
setTimeout(foo, 1000); // RIGHT - we're passing a reference to the function,
// that will be invoked by the js engine after 1000ms
I hope this helps clarify your doubt.
It just seems odd to me to write dbr.onsuccess after dbr has been declared.
var dbr = window.indexedDB.open("Matrix");
dbr.onsuccess = function(myEvent) {}
Q: Is there an alternative way to write line 2 (without being Rube Goldberg)? Maybe something like:
function dbr.onsuccess(myEvent) {
}
I'm just concerned about the order of things. To me, it seems that it's too late to assign an onsuccess function to dbr after it's been created.
var dbr = window.indexedDB.open("Matrix");
is an asynchronous request.
Async requests run in the background and won't run their callbacks until the function completes. So all of the other assignments will happen before any callback functions are run.
The indexedDB is returning you an interface object so that you can define exactly what those callback functions are. You can think of it as you making a request
Hey I want to open matrix
and getting a response back saying
Hey, I'm working on that, here's an object. Please list what you want to have happen when I finish on it.
Then, when it has completed the open operation (and the current function context has completed running) it will look at that object and run accordingly.
The return value of open isn't the real result of the function, its just an object returned for you to tell it what to do. This is similar to a promise/deferred way of doing things, which is different from the normal JS callback model.
This:
function dbr.onsuccess(myEvent) {
}
is not valid syntax. You can't define a property on an object till the object itself has been defined, and javascript doesn't support function declarations for properties. They're only used for top level objects.
dbr.onsuccess = function(myEvent) {}
This is technically a function expression, as it's an assignment statement to the onsuccess property of dbr.
So when you ask if there is more than one way to write a function declaration, the answer is technically no.
A function declaration has only one form:
function foo() {}
Your suggested syntax to declare a function as a property of an object is interesting but a wrinkle in the idea is function hoisting. As you probably already know, functions (including their definitions) available anywhere within scope, even preceding code. Take this example:
foo.bar();
var foo = getFoo();
function foo.bar() {}
Due to function hoisting, foo.bar should be available on line 1. But due to variable hoisting, foo is declared but not yet defined. On line 1 foo has a value of undefined and would result in a TypeError if you tried to invoke function foo.bar.
I think you can say:
var dbr = window.indexedDB.open("Matrix").onsuccess = function(myEvent) {}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the (function() { } )() construct in JavaScript?
I came across this bit of JavaScript code, but I have no idea what to make out of it. Why do I get "1" when I run this code? What is this strange little appendix of (1) and why is the function wrapped in parentheses?
(function(x){
delete x;
return x;
})(1);
There are a few things going on here. First is the immediately invoked function expression (IIFE) pattern:
(function() {
// Some code
})();
This provides a way to execute some JavaScript code in its own scope. It's usually used so that any variables created within the function won't affect the global scope. You could use this instead:
function foo() {
// Some code
}
foo();
But this requires giving a name to the function, which is not always necessary. Using a named function also means at some future point the function could be called again which might not be desirable. By using an anonymous function in this manner you ensure it's only executed once.
This syntax is invalid:
function() {
// Some code
}();
Because you have to wrap the function in parentheses in order to make it parse as an expression. More information is here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/
So to recap quickly on the IIFE pattern:
(function() {
// Some code
})();
Allows 'some code' to be executed immediately, as if it was just written inline, but also within its own scope so as not to affect the global namespace (and thus potentially interfere with or be interfered with by, other scripts).
You can pass arguments to your function just as you would a normal function, for example,
(function(x) {
// Some code
})(1);
So we're passing the value '1' as the first argument to the function, which receives it as a locally scoped variable, named x.
Secondly, you have the guts of the function code itself:
delete x;
return x;
The delete operator will remove properties from objects. It doesn't delete variables. So;
var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);
Results in this being logged:
{'baz':5}
Whereas,
var foo = 4;
delete foo;
console.log(foo);
will log the value 4, because foo is a variable not a property and so it can't be deleted.
Many people assume that delete can delete variables, because of the way autoglobals work. If you assign to a variable without declaring it first, it will not actually become a variable, but a property on the global object:
bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this!
delete bar;
console.log(bar); // Error - bar is not defined.
This time the delete works, because you're not deleting a variable, but a property on the global object. In effect, the previous snippet is equivalent to this:
window.bar = 4;
delete window.bar;
console.log(window.bar);
And now you can see how it's analogous to the foo object example and not the foo variable example.
It means you created an anonymous function, and call it with parameter 1.
It is just the same as:
function foo(x) {
delete x;
return x;
}
foo(1);
The reason that you still get 1 returned is that the delete keyword is for removing properties of objects. The rest is as others have commented, anything wrapped in brackets executes as a function, and the second set of brackets are the arguments passed to that block.
Here's the MDN reference for delete, and the MDN reference for closures, which discusses also anonymous functions.
People normally call these "Immediately Invoked Function Expressions" or "Self Executing Functions".
The point of doing this is that variables declared inside that function do not leak to the outside.
I asked a question on Javascript this points to Window object regarding "this" points to Window object.
here is source code
var archive = function(){}
archive.prototype.action = {
test: function(callback){
callback();
},
test2: function(){
console.log(this);
}
}
var oArchive = new archive();
oArchive.action.test(oArchive.action.test2);
Tim Down wrote "but that function is then called using callback(), which means it is not called as a method and hence this is the global object".
What are differences between calling a function by its actual name and callback() as shown on the source code?
How does console.log(this) in test2 points to Window when it is inside archive.action???
In JavaScript you can invoke functions using 4 different invocation patterns:
Function invocation
Method invocation
Apply/Call invocation
Construction invocation
The patterns mainly differ in how the this parameter is initialized.
When you use oArchive.action.test2(), you would be invoking the test2() function with the method pattern, and in this case this would be bound to the action object. JavaScript will use the method pattern whenever the invocation expression contains a refinement (i.e. the . dot expression or the [subscript] expression).
On the other hand, when a function is not the property of an object, then it is invoked using the function pattern. In this case, the this parameter is bound to the global object, and in fact this is how JavaScript is invoking your callback() function.
Douglas Crockford in his Good Parts book, describes this as a mistake in the design of the language, and suggests some possible workarounds. In you case, one easy workaround would be to invoke the callback using call() or apply(), as Tim Down suggested in your previous question:
callback.call(this);
This works because the Apply/Call invocation pattern lets you choose the value of this, which is what you require.
In javascript the this keyword is set to the owner of a function. Function objects do not maintain their ownership themselves, instead the ownership is deduced from the way we call a function.
eg:
var foo = function() {
alert('hello');
};
var abc = {};
abc.bar = foo;
Simply calling the function like
foo();
gives the interpreter no clue about what object the function might be attached to. It may be attached to multiple objects, it may be a variable etc. So the interpreter sets this to the global object.
But however, when calling a function like
abc.bar();
the interpreter knows that function is attached to abc object, therefore this is set to abc. Even if both bar and foo refer to the same function object, the difference in the calling pattern causes this to behave differently.
I have code like this
var MyObj = {
f1 : function(o){ o.onmousedown = MyObj.f2;},
f2 : function(){ MyObj.f1(); }
}
I would like to know how to refer to MyObj without hardcoding it (i.e. this), so I can change object name without changing the code.
I am interested only in litteral object notation.
EDIT:
I didn't get it right. One of the functions was actually onmousedown event, so this wasn't working in it... This will refer to the object that rised event. I wonder is it still possible to refer to MyObj in such case.
Use this.
Eg:
var MyObj = {
f1 : function(){ ... },
f2 : function(){ this.f1(); }}
One of the functions was actually
onmousedown event, so this wasn't
working in it... This will refer to
the object that rised event. I wonder
is it still possible to refer to MyObj
in such case.
One way follows, though it may not be very useful in this case.
var baz = (function(){ // fake a scope
var foo; // foo will exist in the next statement
foo = { bar: function(){ return foo } };
return foo;
})();
The function wrapper, which is executed immediately, acts to keep variables scoped in that block (later versions of JS by Mozilla have improved scoping syntax, but I'm assuming that's not an option). In this simple example, foo is returned and used as the value for baz, but if you were really doing an assignment and didn't care if foo stayed around, then you'd only need the second two lines. But if it were part of a larger expression, then this idiom might come in handy.