The mere declaration of a function to an object leads to its invocation
var a = {};
a.xyz = new function() {
alert("dosomething");
}
I would expect, that the declared function a.xyz only gets invoked when I call it:
a.xyz();
What is wrong with my assumption?
Remove new and everything will be fine:
var a = {};
a.xyz = function() {
alert("dosomething");
}
JSFiddle: http://jsfiddle.net/vnj8pzm1/
EDIT: More about IIFE - Immediately-Invoked Function Expression (IIFE)
When you put new in front of your function definition, your function is being called as a constructor immediately.
As iceless mentioned, you should not have new in front of your function defintion. However, what iceless mentioned in the comment is incorrect
new function() {} or new function() {}(); will invoke the function just like function() {}(); or (function() {}());
new function() {} will create a new instance of an anonymous type, so in your code a.xyz is an object
if you change it to just function(){}() it would execute the function immediately and return nothing. See http://jsfiddle.net/mendesjuan/kzhg9ggu/
In short:
The new operator create an instance of the object with new, and that's why is executed right after the declaration.
In not so short
xyz= function(){};
Places a reference to an anonymous function into xyz and points to a function.
xyz= new function(){};
Places a reference to a newly constructed instance of an anonymous constructor function, so it will points to an object. Try typeof new function(){} and you will get object.
When the code new function(){alert('foo');} is executed, the following things happen:
A new object is created
The constructor function is called with the specified arguments and this bound to the newly created object. If no argument list is specified, function() is called without arguments.
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead.
Related
Below I am creating an object in JavaScript. Within the constructor I am setting up an event listener. The problem is that when the event gets fired, this.prop cannot be found, and undefined prints out. How do I solve this?
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
When the event handler gets called, "this" no longer references the "someObj" object. You need to capture "this" into a local variable that the mouseMoving function will capture.
var someObj = function someObj(){
this.prop = 33;
var self = this;
this.mouseMoving = function() { console.log(self.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
I'm assuming "someObj is a constructor, i.e. intended to be called with as new someObj(), otherwise "this" will be the global scope.
The "this" keyword can be confusing in JavaScript, because it doesn't work the same way as in other languages. The key thing to remember is that it is bound to the calling object when the function is called, not when the function is created.
The javascript built-in Function.prototype.bind() is intended for this purpose.
For example:
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving.bind(this),true);
}
More on the bind method here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Other wise you have to pass a reference of the object someObj to the element and use that reference in the line:
console.log(this.referenceToObject.prop); //this references the DOM element in an event.
From Section 4.3 of JavaScript: The Good Parts by Douglas Crockford:
Invoking a function suspends the
execution of the current function,
passing control and parameters to the
new function. In addition to the
declared parameters, every function
receives two additional parameters:
this and arguments. The this parameter
is very important in object oriented
programming, and its value is
determined by the invocation pattern.
There are four patterns of invocation
in JavaScript: the method invocation
pattern, the function invocation
pattern, the constructor invocation
pattern, and the apply invocation
pattern. The patterns differ in how
the bonus parameter this is
initialized.
Crockford continues to explains the binding of 'this' in each of these patterns, as follows:
The Method Invocation Pattern:
When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object.
The Function Invocation Pattern:
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language.
The Constructor Invocation Pattern:
If a function is invoked with the new prefix, then a new object will be created with a hidden link to the value of the function's prototype member, and this will be bound to that new object.
The Apply Invocation Pattern:
The apply method lets us construct an array of arguments to use to invoke a function. It also lets us choose the value of this. The apply method takes two parameters. The first is the value that should be bound to this. The second is an array of parameters.
You could use a variable named 'me', to avoid conflict with the global JavaScript variable 'self':
function someObj() {
var me = this;
this.prop = 33;
this.mouseMoving = function() {
alert(me.prop);
}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
First, you need to understand how 'this' works in JavaScript. 'this' keyword doesn't behave how it behaves in other languages like C# or Java. Read following post to understand more,
What is the rationale for the behavior of the 'this' keyword in JavaScript?
Once you understand that, as Matthew outlined in his code, you can save reference to 'this' and use that reference inside the mouseMoving function.
Though overall, I will advise that you use a JavaScript framework (e.g. jQuery, YUI, MooTools) which will take care of these issues for you. E.g. In Internet Explorer, you use addEvent to attach event and not addEventListenr.
You have some typos on your function declaration.
Your prop variable is also defined as a "public" or "visible" member (by using this.prop), doing so forces you to store the reference of this from the outer function (that is actually a reference to the object instance), as a "private" member of the function (using var) to get access the instance of the created object and read the "public" prop member.
You have some alternatives to rewrite this code:
function someObj (){
var self = this;
this.prop = 33;
this.mouseMoving = function() { alert(self.prop);} // You access the current
// instance, stored in *self*
// since *this*, inside the
// function, is in another
// context.
//...
}
var mySomeObj = new someObj(); // Object instantiation
Or you could:
function someObj (){
var prop = 33;
this.mouseMoving = function() { alert(prop);}
//...
}
var mySomeObj = new someObj(); // Object instantiation
The variables declared with var, are accesible to the functions declared inside of the major constructor function, this feature is known as Closures.
Below I am creating an object in JavaScript. Within the constructor I am setting up an event listener. The problem is that when the event gets fired, this.prop cannot be found, and undefined prints out. How do I solve this?
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
When the event handler gets called, "this" no longer references the "someObj" object. You need to capture "this" into a local variable that the mouseMoving function will capture.
var someObj = function someObj(){
this.prop = 33;
var self = this;
this.mouseMoving = function() { console.log(self.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
I'm assuming "someObj is a constructor, i.e. intended to be called with as new someObj(), otherwise "this" will be the global scope.
The "this" keyword can be confusing in JavaScript, because it doesn't work the same way as in other languages. The key thing to remember is that it is bound to the calling object when the function is called, not when the function is created.
The javascript built-in Function.prototype.bind() is intended for this purpose.
For example:
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving.bind(this),true);
}
More on the bind method here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Other wise you have to pass a reference of the object someObj to the element and use that reference in the line:
console.log(this.referenceToObject.prop); //this references the DOM element in an event.
From Section 4.3 of JavaScript: The Good Parts by Douglas Crockford:
Invoking a function suspends the
execution of the current function,
passing control and parameters to the
new function. In addition to the
declared parameters, every function
receives two additional parameters:
this and arguments. The this parameter
is very important in object oriented
programming, and its value is
determined by the invocation pattern.
There are four patterns of invocation
in JavaScript: the method invocation
pattern, the function invocation
pattern, the constructor invocation
pattern, and the apply invocation
pattern. The patterns differ in how
the bonus parameter this is
initialized.
Crockford continues to explains the binding of 'this' in each of these patterns, as follows:
The Method Invocation Pattern:
When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object.
The Function Invocation Pattern:
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language.
The Constructor Invocation Pattern:
If a function is invoked with the new prefix, then a new object will be created with a hidden link to the value of the function's prototype member, and this will be bound to that new object.
The Apply Invocation Pattern:
The apply method lets us construct an array of arguments to use to invoke a function. It also lets us choose the value of this. The apply method takes two parameters. The first is the value that should be bound to this. The second is an array of parameters.
You could use a variable named 'me', to avoid conflict with the global JavaScript variable 'self':
function someObj() {
var me = this;
this.prop = 33;
this.mouseMoving = function() {
alert(me.prop);
}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
First, you need to understand how 'this' works in JavaScript. 'this' keyword doesn't behave how it behaves in other languages like C# or Java. Read following post to understand more,
What is the rationale for the behavior of the 'this' keyword in JavaScript?
Once you understand that, as Matthew outlined in his code, you can save reference to 'this' and use that reference inside the mouseMoving function.
Though overall, I will advise that you use a JavaScript framework (e.g. jQuery, YUI, MooTools) which will take care of these issues for you. E.g. In Internet Explorer, you use addEvent to attach event and not addEventListenr.
You have some typos on your function declaration.
Your prop variable is also defined as a "public" or "visible" member (by using this.prop), doing so forces you to store the reference of this from the outer function (that is actually a reference to the object instance), as a "private" member of the function (using var) to get access the instance of the created object and read the "public" prop member.
You have some alternatives to rewrite this code:
function someObj (){
var self = this;
this.prop = 33;
this.mouseMoving = function() { alert(self.prop);} // You access the current
// instance, stored in *self*
// since *this*, inside the
// function, is in another
// context.
//...
}
var mySomeObj = new someObj(); // Object instantiation
Or you could:
function someObj (){
var prop = 33;
this.mouseMoving = function() { alert(prop);}
//...
}
var mySomeObj = new someObj(); // Object instantiation
The variables declared with var, are accesible to the functions declared inside of the major constructor function, this feature is known as Closures.
I am just getting more into javascript and wandering what is the difference between
var myfunc = function(){
publicfunctions = {}
publicfunctions.function1 = function(){do smthing and return}
return publicfunctions
}
and
var myfunc = function(){
this.function1 = function(){do smthing and return}
}
It seems to me that both doing the same thing
Also can someone explain what is difference between
var func = (function myfunc(){ .. do smthing and return .. })();
and
var func = function myfunc(){ .. do smthing and return .. }
var newfunc = new myfunc()
Thanks
Let's go step by step.
example:
a) you define a function that returns an object (careful with variable declaration - you should declare it with var keyword in order to scope it to your function. That objects has a single property that points to a function. Never the less, your first function is assigned to a variable myfunc
Now, if you try to call myfunc(), you'll get an object with single property function1. Nothing special here.
b) you define a function again and assign it to myfunc variable, only this time it contains this keyword which assumes you're trying to utilize this function as a constructor. In this example, merely calling myfunc produce no output since you haven't returned anything from a function. However, calling a function with preceding keyword new will result in object creation.
var myObj = new myfunc();
// `this` keyword now refers to myObj which means myObj can call `function1`
example:
a) On the righthand side is something that is called IIFE (or Immediately Invoked Function Expression). Basically means, a function expression that is created and executed, well, immediately. So func should receive whatever that function returns.
b) Yet again, facing a constructor, only this time you actually assumed myfunc is a constructor when you added new keyword before myfunc execution. Creates an object to whic newfunc now points to and has authority over.
Note:
In constructor functions (the ones that you call with new keyword), this is implicitly returned and no need for explicit return. Now, if you want to test it and return something else instead, I'll leave it up to you to explore and see what you'll end up with. :)
Since it's a broader topic in itself, I recommend this excellent book by Nicholas Zakas. It really answers a lot of JS questions.
My question is regarding the resulting object from using new function(){ ... } over new Function();
My understanding so far/assumption
When we create a function using Function() or new Function() we get a object configured as a function (it's internal slots indicate a function type object)
With or without the new operator, the Function() constructor returns a new function object
Using a function expression returns a function object which internally uses the Function() constructor
A function expression provides optimization with parsing the function body
My question
Following my assumption above, why does new Function(); and new function(){ ... } return different things?
The first returns a function object, but the latter returns a standard object. Given that a function expression under the hood uses the Function() constructor, why does the latter not behave the same as new Function();?
Using new function(){ ...} I would expect a function object, not a standard object.
The following lines are essentially the same:
function foo(...) {...}
var foo = function (...) {...};
var foo = new Function (...);
They all declare a new function (which is an object, that is an instance of Function, which inherits the Object prototype, ...) in the current scope which can be accessed via the foo variable.
The new keyword instantiates an object from a function which allows you to create something similar to a class instance in a standard OOP language.
Continuing the example from above:
var bar = new foo(...)
would instantiate an instance of the foo function in the current scope which could be accessed via the bar variable.
why does new Function(); and new function(){ ... } return different things?
I'm going to rephrase the example slightly. Instead of:
new Function()
//and
new function(){ ... }
I'm going to use
new Function()
//and
var foo = function () { ... };
new foo();
The reason that new Function() returns a different thing than new foo() is entirely because Function is a different function from foo.
I expect that you're not confused by the fact that new Object() returns a different object with different features than new Array(). The exact same thing is happening here.
Given that a function expression under the hood uses the Function() constructor, why does the latter not behave the same as new Function();?
under the hood the later expression is essentially:
new (new Function ( ... ))
new Function(...) returns a new function, while new function() {...} returns a new Object.
Basically, Function is just a way to evaluate a piece of code.
Objects are a way, to store data in javascript.
Side note: you can technically do
new (new Function(...))
wich returns a new object.
Can someone explain in detail what this snippet of js does?
(function (window) {
var test = window['test'] = {};
test.utils = new(function(){ ... })();
})(window);
I understand that the function is not globally scoped. I understand that it is creating a variable called test that points to a property in the window object that is an empty object. I also understand that utils is a property of test.
I don't understand what the purpose of the last part is (window); or why the utils function is being designated as new.
Please explain.
It creates a function and calls it immediately, passing in window. The function receives an argument called window and then creates an empty object on it which is available both as a property on window called test and as a local variable called test. Then it creates an object by calling a function via new and assigns that object to test.utils.
I don't understand what the purpose of the last part is (window);...
It doesn't really serve any purpose in the code you've quoted, because the symbol passed into the main (outer) function, window, is the same as the name of the argument receiving it. If their names were different, then it would serve a purpose, e.g.:
(function(wnd) {
})(window);
That would make window available within the function as wnd.
or why the utils function is being designated as new.
utils won't be a function (at least, not unless the code you've replaced with ... is doing something really strange), it will be an object created by calling that function.
The whole thing could be rewritten more clearly:
(function(window) {
var test;
test = {};
window['test'] = test;
test.utils = new NiftyThing();
function NiftyThing() {
}
})(window);
That still does the window thing for no reason, but hopefully it makes it clear what the new(function() { ... })(); bit was doing.
First of all, this is a self-invoked function.
It's invoked itself giving the window object as function input argument in order to ensure that, inside the whole function, window will have the expected meaning.
test.utils = new(function(){ ... })(); <--- This is an object constructor.
When the function is called using the new operator, it turns into an object constructor.
For example:
var conztructor = function() {
this.name = "Matias";
};
var obj = new conztructor();
alert(obj.name); // <--- This will alert "Matias"!
The purpose of (window); is creating a new variable and reference holding the JavaScript Window object instance, avoiding that other libraries may reuse the window (or any other) identifier and your own library may break because of this situation.
This is nice in order to avoid altering global scope identifiers that may be used by other libraries.
UPDATE
In response to some comments, run this code:
http://jsfiddle.net/wChh6/5/
What is happening here is that a new anonymous function is being declared. The last part with (window) makes a call to that function, passing window as a parameter.
Inside, the call to test.utils = new(function(){ ... })(); creates a new object (with contents defined by the function passed to new) and assigns it to test.utils.
When you define a function with last parentetheses, the function is executed itself after loading with the parameter given, in your case window
(function (window) {
var test = window['test'] = {};
test.utils = new(function(){ ... })();
})(window);
JS function definition : meaning of the last parentheses