This is probably pretty easy, yet I am confused, so maybe I might still learn something more today. I am trying to do the following:
var myObj = {};
myObj.src = {}
myObj.src.A = ['1.png','2.png','3.png'];
myObj.A = new Image();
myObj.A.src = this.src.A[0];
This will result in an Uncaught TypeError: Cannot read property 'A' of undefined error.
When I use myObj.src.A[0] instead of this it is working fine.
What would be the correct way to use this in this context?
this refers to the object context in which the code is executing. So if an object has a method aMethod, then inside aMethod this references the object that owns it.
I'm assuming your code there is running in the global namespace, so this is undefined. Really you just want myObj.A.src = myObj.src.a[0];.
http://www.quirksmode.org/js/this.html
The this keyword is always different depending on the scope involved. In the code snippet you've posted above, assuming that you're just putting this in the document somewhere in the head, this refers to the page itself. So, it's fairly obvious at that point that this.src.A will be undefined. If you were to apply an event to it with a delegate such as:
myObj.click = function() {
alert(this.src.A[0]);
}
The this keyword receives a new scope belonging to the owner of the delegate (in this case myObj). this is very easy to track so long as your clearly define your scopes and your scope boundaries.
this does not refer to var myObj in the case of your code. It is likely that if you are not inside the scope of a function or an objects method then this is referring to the DOM window which has no attribute src.A
this in JavaScript depends heavily on the context in which a function is called. If your code is (as it looks to be above) just hanging out in a script tag in the page, then this is going to be the "global" context -- which in the browser is the window object.
Generally, this refers to the object/scope a function belongs to, but there's a number of special (and useful) cases that happen because functions are first class values that can be assigned to different objects and invoked in various contexts.
Some lengthy elaboration others have written might be helpful:
https://stackoverflow.com/a/3320706/87170
http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/
http://net.tutsplus.com/tutorials/javascript-ajax/fully-understanding-the-this-keyword/
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special_Operators/this_Operator
It can seem a little tricky at the start, particularly if you're used to languages in which this is always one thing, but after you learn a few rules it becomes fairly straightforward and actually very useful.
myObj.src.A[0] would be correct in this context because this references its immediate parent.
Related
Today while working my mind was stack at some point in javascript.
I want to know that what is basic difference between
function FunctionName(){
//Code goes here;
}
And
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
//Code goes here;
}
Both are working same. Then what is difference between then. Is there any advantage to use function with object name?
I have read Question. But it uses variable and assign function specific variable. I want to create object and assign multiple function in single object.
The first one defines a global function name. If you load two libraries, and they both try to define FunctionName, they'll conflict with each other. You'll only get the one that was defined last.
The second one just has a single global variable, MyFuncCollection. All the functions are defined as properties within that variable. So if you have two collections that try to define the same function name, one will be FuncCollection1.FunctionName, the other will be FuncCollection2.FunctionName, and there won't be any conflict.
The only conflict would be if two collections both tried to use the same name for the collection itself, which is less likely. But this isn't totally unheard of: there are a few libraries that try to use $ as their main identifier. jQuery is the most prominent, and it provides jQuery.noConflict() to remove its $ binding and revert to the previous binding.
The short answer is, the method in object context uses the Parent Objects Context, while the "global" function has its own object context.
The long answer involves the general object-oriented approach of JavaScript, though everything in JavaScript is an object you may also create arrays with this Method.
I can't really tell you why, but in my experience the best function definition is neither of the top mentioned, but:
var myFunction = function(){};
It is possible to assign function to variables, and you may even write a definition like this:
MyObject.myMethod = function(){};
For further reading there are various online Textbooks which can give you more and deeper Information about this topic.
One main advantage I always find is cleaner code with less chance of overwriting functions. However it is much more than that.
Your scope changes completely inside the object. Consider the following code ::
Function:
function FunctionName(){
return this;
}
FunctionName()
Returns:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
Object:
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
return this;
}
MyFuncCollection.FunctionName()
Returns:
Object {}
This leads to some nice ability to daisy chain functions, amongst other things.
The first:
function functionName (){
//Code goes here;
}
Is a function declaration. It defines a function object in the context it's written in.
Notice: this doesn't have to be the global context and it doesn't say anything about the value of this inside it when it's invoked. More about scopes in JavaScript.
Second note: in most style guides functions are declared with a capitalized name only if it's a constructor.
The second:
var myFuncCollection = {};
myFuncCollection.functionName = function () {
//Code goes here;
};
notice: don't use the new Object() syntax, it's considered bad practice to use new with anything other then function constructors. Use the literal form instead (as above).
Is a simple assignment of a function expression to a property of an Object.
Again the same notice should be stated: this says nothing about the value of this when it's invoked.
this in JavaScript is given a value when the function object is invoked, see here for details.
Of course, placing a function on an Object help avoiding naming collisions with other variables/function declarations in the same context, but this could be a local context of a function, and not necessarily the global context.
Other then these differences, from the language point of view, there's no difference whatsoever about using a bunch of function declarations or an Object with bunch of methods on it.
From a design point of view, putting methods on an Object allows you to group and/or encapsulate logic to a specific object that should contain it. This is the part of the meaning of the Object Oriented Programming paradigm.
It's also good to do that when you wish to export or simply pass all these functions to another separate module.
And that's about it (:
Is there any practical difference between using the internal or external object reference when creating an object using immediately invoked function expression? Example:
var external = (function(){
var internal = {};
internal.a = function(){
//... do stuff
}
internal.b = function(){
internal.a();
// ^ OR v
external.a();
}
return internal;
})();
Both work. The only difference I could think of is possibly internal is cleaned up after being invoked if there's no direct calls to it, but that may be moot since the same object lives in external. If there's a duplicate, forgive me - I was unable to articulate what I wanted to know well enough for a search engine to give me a clear answer.
Thanks!
They are the exact same thing (as #Pointy pointed out, they are the same thing until someone changes external on the outside), but it just feels weird to use external here, and it is not pretty clear because you are using it inside its own definition sort of.
One interesting difference is that the reference to external will mean that the lexical scope that contains the external var declaration will be pinned from inside the object. That could be interpreted as a memory leak, depending on what happens to the object.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
Today I ran into a very odd problem using Javascript's prototype and the this reference.
Basically, I have two objects. One object makes use of a div element and makes is possible to register an onclick event on the div. The other object makes use of this functionality and registers the onclick event using the first object.
Here is the code:
My first object, which takes care of the div:
DivObject = function() {};
DivObject.prototype.setClickListener = function(clickListener){
document.getElementById("myDiv").onclick = function(e){
clickListener(e);
};
};
My second object uses this functionality:
MainObject = function(){
this.myString = "Teststring";
this.divObj = new DivObject();
this.divObj.setClickListener(this.handleClick);
};
MainObject.prototype.handleClick = function(e){
// do something with e
};
The problem is, that inside MainObject.prototype.handleClick, the this reference refers to the window object, not to the MainObject. So, console.log(this) inside this function logs [Object window].
You can see this behaviour on jsfiddle.
As a workaround, I use the setClickListener function as follows:
var thisRef = this;
this.divObj.setClickListener(function(e){
thisRef.handleClick(e);
});
Now, the this reference in my handleClick function refers to my MainObject (as I want it to be).
See this workaround on jsfiddle.
My questions are:
Why does the this reference one time refer to the window object and one time to the this reference of my object? Is it overridden somewhere? I always thought using this in my object I can be sure that it is really the this reference of my object? Is the workaround I am using now the way how this problem should be solved or are there any other, better way to handle this case?
Your questions:
Why does the this reference one time refer to the window object and one time to the this reference of my object?
Other than using bind, the value of a function's this is set by how the function is called. When you do:
this.divObj.setClickListener(this.handleClick);
you are assigning a function reference, so the function is called later without any qualification (i.e. it's called as just handleClick rather than this.handleClick). On entering the function, because its this isn't set by the call, it will default to the global (window) object, or in strict mode remain undefined.
Is it overridden somewhere?
No, the value of this is set on entering an execution context. You can't overwrite it or directly assign to it, you can only set it in the call (e.g. as a method of an object, using new, apply, call) or using bind (also, arrow functions adopt the this of their enclosing lexical execution context).
I always thought using this in my object I can be sure that it is really the this reference of my object?
At the point you make the assignment, this is what you expect. But you are assigning a reference to a funciotn, not calling the function, so its this isn't set at that moment but later when it's called.
Is the workaround I am using now the way how this problem should be solved or are there any other, better way to handle this case?
Your work around is fine (and a common fix), it creates a closure so may have minor memory consequences but nothing serious. For very old versions of IE it would create a memory leak due to the circular reference involving a DOM object, but that's fixed.
The bind solution is probably better from a clarity and perhaps maintenance viewpoint. Remember to include a "monkey patch" for browsers that don't have built–in support for bind.
Please post code on SO, there is no guarantee that code posted elsewhere will continue to be accessible. The work around code:
MainObject = function(){
this.myString = "Teststring";
this.divObj = new DivObject();
var thisRef = this;
this.divObj.setClickListener(function(e){
thisRef.handleClick(e);
});
};
You could fix this by using .bind():
this.divObj.setClickListener(this.handleClick.bind(this));
See the demo.
I've been doing some javascript reading, and I've gathered that a closure has access only to the closure "wrapping" it, or, you might say it's immediate parent. Now I've been playing a bit, and I see in this jsfiddle that even deep nested functions have access to to vars defined way up.
Can anyone please explain that? Or explain what have I got completely wrong?
http://jsfiddle.net/tPQ4s/
function runNums() {
this.topVar = 'blah';
return function(){
(function() {
(function() {
console.log(topVar);
})();
})();
}
}
var someFunc = runNums();
someFunc();
Without going too deep into the details, a closure technically describes a array like variable within the such called Activation Object that is handled from the javascript engine. An ActivationObject contains Variables declared by var, function declarations and formal parameters.
That means, anytime a new function (-context) is invoked, internally a new Activation Object is created. That object is part of the new Execution Context, a typicall EC looks like:
this context variable
Activation Object
[[Scope]]
The interesting part here is [[Scope]]. That variable contains all Activation Objects of all parent context and is filled when the EC is called. So now, when a function wants to access a variable, the name resolution process first looks into its own Activation Object, if nothing is found the search continues in the "Scope chain", which is just an Indexed search through our [[Scope]] variable (which again, is an array of parent contexts). Thats why we also speak a lot about "lexical scope" in ECMA-/Javascript.
Note: The above behavior is not described entirely, that would need several pages of text. Also it describes the ECMAscript3 262 specification. Things work a little different in ES5, but its still around the same thing
That is because the chain runs further up to the top context.
In the example, that would be:
window < runNums < anonymous < anonymous < anonymous
Variables living in any of these will be available in the last anonymous function. In runNums, only variables living in runNums or window will be available. In the first anonymous function, only its variables and those living in runNums or window will be available, etc.
this is nothing but the Window object here.
Here runNums is a global function and runNums() is equal to window.runNums(). So this is window and this.topVar is window.topVar. Obviously it will be accessible from anywhere.
Try this and see the difference
var someFunc = new runNums();
someFunc();
The deep nested functions have not been executed. You did not return them for executing.
Are there any benefits to using the 'window' prefix when calling javascript variables or methods in the window object? For example, would calling 'window.alert' have an advantage over simply calling 'alert'?
I can imagine using the prefix could give a small performance boost when the call is made from inside some function/object, however I rarely see this in people's code. Henceforth this question.
This is useful when attempting to test global object values. For example, if GlobalObject is not defined then this throws an error:
if(GlobalObject) { // <- error on this line if not defined
var obj = new GlobalObject();
}
but this does not throw an error:
if(window.GlobalObject) { // Yay! No error!
var obj = new GlobalObject();
}
Similarly with:
if(globalValue == 'something') // <- error on this line if not defined
if(window.globalValue == 'something') // Hurrah!
and:
if(globalObj instanceof SomeObject) // <- error on this line if not defined
if(window.globalObj instanceof SomeObject) // Yippee! window.prop FTW!
I would not expect to see a significant performance difference, and the only other reason you might do this is to ensure that you are actually getting a value from the global scope (in case the value has been redefined in the current scope).
I doubt there is any measurable performance benefit. After all the scope chain would be scanned for the identifier window first then the window object would be scanned for the desired item. Hence more likely it would be deterimental to performance.
Using window prefix is useful if you have another variable in scope that would hide the item you may want to retrieve from the window. The question is can you always know when this might be? The answer is no. So should you always prefix with window? What would you code look like if you did that. Ugly. Hence don't do it unless you know you need to.
Retrieved from Google (http://www.techotopia.com/index.php/JavaScript_Window_Object):
The window object is the top-level object of the object hierarchy. As such, whenever an object method or property is referenced in a script without the object name and dot prefix it is assumed by JavaScript to be a member of the window object. This means, for example, that when calling the window alert() method to display an alert dialog the window. prefix is not mandatory. Therefore the following method calls achieve the same thing:
window.alert()
alert()
However, I read but have not had time to test the following from:
(http://www.javascriptref.com/reference/object.cfm?key=20)
One place you'll need to be careful, though, is in event handlers. Because event handlers are bound to the Document, a Document property with the same name as a Window property (for example, open) will mask out the Window property. For this reason, you should always use the full "window." syntax when addressing Window properties in event handlers.
As far as performance, I think AnthonyWJones has it covered.
One use of the window prefix is to explicitly make something available outside the current scope. If you were writing code in a self-invoking function to avoid polluting the global scope, but there was something within that you did want to make globally available, you might do something like the following:
(function(){
function foo(){
//not globally available
}
function bar(){
//not globally available
}
window.baz = function(){
//is globally available
foo();
bar();
};
})();
I imagine that the performance benefit here is amazingly insignificant at best, if there is one at all.
It only matters if you're using frames and doing a bunch of javascript calls across frames, and even then only specific scenarios warrant the necessity of referencing window explicitly.
When you use the prefix, you're making it explicit you're using the "global" definition of the variable, not a local one. (I'm not sure whether / how you can inject variables into a scope in JS, except the weirdness with this and inline event handlers.) YMMV, you may either prefer the clarity, or find it to be just clutter.