JavaScript的this,你有搞懂過嗎?

JavaScript的this關鍵字隨處可見,但對this的誤解更常見  …
一起來搞懂 JavaScript this 吧!

本文翻譯自 http://javascriptweblog.wordpress.com/2010/08/30/understanding-javascripts-this/

你需要知道什麼

每一個執行的 context 都有一個對應的 This Binding ,並且這個 This Binding 的生命週期與執行的 context 等長,並且是一個不會改變的值。執行 Context 有三種:

 

執行context 語法 this 是
Global n/a global object (e.g. window)
Function Method call:
myObject.foo();
myObject
Function Baseless function call:
foo();
global object (e.g. window)
(undefined in strict mode)
Function Using call:
foo.call(context, myArg);
context
Function Using apply:
foo.apply(context, [myArgs]);
context
Function Constructor with new:
var newFoo = new Foo();
the new instance
(e.g. newFoo)
Evaluation n/a value of this in parent context
  1. 全域 (global context)
    this 被綁定為全域的物件,通常就是 window.alert(this); //window 
  2. 函式 (function context)
    至少有五種方式可以執行函式,this 的意義依呼叫的方式不同會有不同的值

    1. 當作一個物件的 method 執行
      this 就是對應的物件

      var a = {
          b: function() {
              return this;
          }
      };
      
      a.b(); //a;
      
      a['b'](); //a;
      
      var c= {};
      c.d = a.b;
      c.d(); //c
    2. 沒有 base 的函式執行
      this 是全域的 window 物件

      var a = {
          b: function() {
              return this;
          }
      };
      
      var foo = a.b;
      foo(); //window
      
      var a = {
          b: function() {
              var c = function() {
                  return this;
              };
              return c();
          }
      };
      
      a.b(); //window
    3. 透過 Function.prototype.call 執行
      this 根據傳入的參數決定
    4. 透過 Function.prototype.apply 執行
      this 根據傳入的參數決定

      var a = {
          b: function() {
              return this;
          }
      };
      
      var d = {};
      
      a.b.apply(d); //d
    5. 透過 new 執行 constructor
      this 等於新生成的物件

      var A = function() {
          this.toString = function(){return "I'm an A"};
      };
      
      new A(); //"I'm an A"
  3. Evaluation context
    this 的值跟呼叫所在的 this 同義

    alert(eval('this==window')); //true - (except firebug, see above)
    
    var a = {
        b: function() {
            eval('alert(this==a)');
        }
    };
    
    a.b(); //true;



Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *