Waiting for the correct call context (this) in the JavaScript object

Consider this:

window.onload = function () { myObj.init(); }; var myObj = { init: function () { console.log("init: Let call the callMe method..."); //callMe is not defined... callMe(); //Works fine! this.callMe(); }, callMe: function () { console.log('callMe'); } }; 

Since the init function is called this way (myObj.init), I expect this be myObj in the init function. And if so, why does the callMe function not work? How can I call a callMe function without using this context in the init element? (Actually, it is too annoying to call object methods using this again and again through functions. So what is the point with one object?)

I would like to know how I can fix this so that the callMe method is called using the first call in the code above?

+4
source share
2 answers

this never implied in JavaScript, as in some other languages. Although there are ways to do this, for example, using the with statement:

 init: function () { console.log("init: Let call the callMe method..."); // Make `this` implicit (SEE BELOW, not recommended) with (this) { // Works callMe(); } }, 

... this is usually a bad idea . Douglas Crockford probably wrote one of the best descriptions of why this is a bad idea, which you can find here here . Basically, using with makes it almost impossible to tell what the code will do (and slows the code down if you do anything else in this with statement that doesn't come from the this object).

This is not the only way JavaScript this not the same as in some other languages. In JavaScript, this completely determined by how the function is called, not where the function is defined. When you execute this.callMe() (or the equivalent of this["callMe"]() , or, of course, foo.callMe() , etc.), two occur: the function reference is retrieved from the property, and the function is called special way to set this as the object from which the property was obtained. If you do not call the function through the property this way, the call does not set any specific value for this , and you get the default value (which is a global object; window in browsers). This is a call action that sets this . I studied this in detail in several articles on my blog, here and.

This (no pun intended) can be made even more clear if you look at the JavaScript call and apply functions that are available for all function objects. If I do this:

 callMe.call({}); 

... it will call the callMe function with an empty object ( {} ) like this .

So basically, just get used to typing this . :-) It is still useful to have properties and methods associated with the object, even without the syntactic convenience (and confusion!) Of the implicit this .

+8
source

You can also use a module template that captures all private variables inside a closure, so you can use them without this , since they are in the same area . Then you choose which methods / variables you want to make public:

 var myObj = (function () { var init = function () { callMe(); // This now works }; var callMe = function () { ... }; // Now choose your public methods (they can even be renamed): return { init: init, // Same name callMyName: callMe // Different name }; }) (); 

Now:

 myObj.init(); // Works myObj.callMyName(); // Works myObj.callMe(); // Error 
+2
source

All Articles