简体   繁体   中英

Javascript `this` object == `window` in member function

In some of my Javascript objects I find that my this pointer is correct - these are new Func() -type objects - when created, but in the assigned methods it can be wrong.

function Confused() {
   console.log("checking",this==window,"is always false");
   this.method = function() {
       console.log("checking",this==window,"is true for some funcs but not others");
   };
};

On some calls to (new Confused()).method() - it seems to have lost it's this pointer. The times this happen seem dependent on the function, rather than random; its something in the code around how I'm creating classes that is causing this.

An example is online at http://williame.github.com/barebones.js/ and the member callback G3D._file_loaded has a wrong this pointer when called sometimes.

Why, and how do I fix it?

There are 4 ways to use a function in Javascript what each of these does is change what the content of this is :

  • function calls: this = global object (window in browser)
  • method calls: this = object it is called from.
  • constructor calls: this = new object you are creating.
  • call/apply calls: this = object you passed.

In your case this == window when you call the function directly ( Confused() ) but if you call using new ( new Confused() ) then it will be the new object you are creating.

The this keyword refers to the calling context. It is never wrong but it may not be what you would have expected it to be.

You can manually set context when calling a function, if you call it with .call or .apply .

Furthermore, if a reference to window is what you want, why not use window instead of this ? It's a way more reliable means of accessing the window object.

In addition to David Hedlunds explanation, you can "work around" that problem like this:

function Confused() {
   var that = this;
   console.log("checking",that==window,"is always false");
   this.method = function() {
       console.log("checking",that==window,"is always false");
   };
};

The problem is that the whoever actually invokes your function has control over context of your function. If you do not control the function invocation (that is, if you can't modify the code), than you are stuck with the solution I gave (at least I know of no other way).

While the solution seems a little "hackish", it really isn't if you think about it. It simply harnesses the power given to you by closures :D

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM