玩轉Javascript this用法

  在web項目中Javascript是一門必需要掌握的動態語言,基於Javascript的框架大多離不開不了最基礎的Javascript的用法和原理。本文主要是總結一下Javascript中那萬惡的this關鍵字。javascript

  開門見山,拋出一個觀點:「Javascript中this永遠是指向調用它的對象」。下面我會舉3個最有表明性的例子來驗證個人這個觀點。java

例一 對象方法調用

    var x = 1;
  function testThis(){
    console.log(this.x);
  } 

     testThis();

// 這裏聲明瞭一個全局變量x,一個全局方法,這兩個對象都綁定在Window上,因此當運行testThis()的結果就是取Window對象上的x成員,結果是1

  var o={};
  o.x = 5;
  o.method = testThis;

     o.method();

// 此時,咱們講o對象的method指向了testThis, 當調用它的時候,this指向調用他的對象,這是x就是去o對象的x,結果是5

  這個例子十分基礎,也就是常見的對象調用方法的時候,方法裏面的this就是指向調用他或者是擁有他的對象web

例二 構造函數建立

    var x = 2;    
  function test(){
    this.x = 1;
  }

  var o = new test();
  console.log(o.x);  // 1

//這就是javascript中的構造函數,經過new來建立一個實例,這裏取的值是綁定在對象o裏面的x,因此是1

//下面這個例子是Angular中的Service,你能夠直接理解成他會經過第二個參數new一個單例對象
     app.service("MyService", function ($http, $modal) {
          this.test = function() {
                console.log(this);
                test2();
          }
          
           function test2() {
                console.log(this)
           }
     }        

     MyService.test() // 打印 MyService {test: function} 和 Window {}

//這裏log出來雖然test2()能夠被test1()調用,但它其實並不屬於Service, 因此若是test2裏面調用this,就會出現常見的錯誤,哎呀媽呀,咋調不了本身的方法?!

  這個例子咱們項目中常常出現,並且很難解釋清楚,就像還有人問我爲何controller中不直接使用this,而是要用$scope來綁定方法和變量,固然用this可以取代部分$scope,可是不免遇到this的上下文不一樣引發的一系列問題。這個問題的關鍵就是test2方法並不屬於對象Service,可是因爲在service閉包(closure)裏面,他能夠被Service調用,因此test2裏面的this就不是指向Service,從而調用Service裏面的其餘方法就會報錯。閉包

例三 改變this指向

  function test(){
    console.log(this.x);
  }
  var o={};
  o.x = 1;
  o.m = test;

  o.m.apply({x:5});  //5
    o.m.call()             // undefined

//經過apply/call來指定調用函數的this做用上下文,都是指用參數對象來調用o對象的函數,默認參數是Global

  其實經過這個例子,你們就已經能夠看到this的指向是不肯定的,this值在進入上下文時肯定,而且在上下文運行期間永久不變。上面的例子改變this的上下文,致使兩次結果不一致也是最好的證據。app

最後

  本文最大的做用就是若是看完本文你可以理解this爲何有時候會跟本身指望不同,並且能獲得一個避免這樣問題發生的解決方案,那個人目的就達到了。很幸運你能看到這裏,解決方案呈現給你們:就像Angular要將屬性和方法給你提供一個$scope來綁定屬性,也像coffeeScript會在對象一開頭有這麼個賦值「 _this = this」,咱們在本身的js實踐中不妨定義"val self = this",在以後的做用域裏面用self來操做對象的屬性,這是解決之道。框架

相關文章
相關標籤/搜索