<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      理解JavaScript中的“this”

      對于javascript的初學者來說,一般對“this”關鍵字都感到非常迷惑。本文的目的旨在讓你全面的了解“this”,理解在每一個情景下如何使用“this”,希望通過本文,可以幫助同學們不在害怕“this”!!

       

      從生活中發現

      其實“this”就是我們平時用的一個代詞。打個簡單的比喻:

           “小豆豆是一個很幽默的人,非常喜歡看《暴走漫畫》”

      但是你也可以這樣寫:

           “小豆豆是一個很幽默的人,小豆豆非常喜歡看《暴走漫畫》”

      但是日常生活中我們會一直用這種方式來描述一個人嗎?如果你的回答是Yes,好吧,估計再也沒有人愿意跟你做朋友了,我沒騙你…(開個玩笑:-) )。   所以,人類就發明了這樣一種看似高端、洋氣、上檔次的代名詞,說白了javascript中的“this”也就是這么一個東東。

      一個簡單的例子:

      person = {
       firstName: "zhou",
       lastName: "Quan",
       
       fullName:function(){
       alert(person.firstName + " " + person.lastName);//Zhou Quan
       
       alert(this.firstName + " " + this.lastName);//Zhou Quan
       }
      }
       
      person.fullName();

      我們可以根據前面所說的方式來理解這個程序的結果, 但是這僅僅停留在表面而已,下面我們再進行更深一步的理解。

       

      this基礎

      首先,我們知道javascript中所有的函數都擁有屬性,就像一個對象也擁有屬性一樣。當一個函數被執行時,他就擁有了“this”屬性--調用this所在函數的對象。this永遠指向一個獨一無二的對象,這個對象通常包含一個函數/方法,雖然它也可以被用在一個函數之外的全局作用域中(global scope)。注意:在嚴格模式(strict mode)中,在全局函數或者匿名函數中this的值為“undefined”(也就是說this沒有綁定任何對象)。

      “this”被用在一個函數內部(假設是function A),那么它包含的值是調用“function A”的對象。我們需要this來訪問調用“function A”的對象的屬性和方法,特別是當我們不知道到這個對象名叫什么的時候,或者這個對象沒有名字的時候。其實,this就是調用當前函數的對象的一個代名詞!

      我們來舉一個簡單的例子:

      var person = {
       firstName: "zhou",
       lastName: "Quan",
       //this將為person對象,因為person對象會調用FullName方法
       FullName:function(){
       alert(this.firstName + " " + this.lastName); //zhou Quqn
       }
      }
      person.FullName();
       
      再來看一個jquery中this的簡單應用:
      $ ("button").click (function (event) {
       // $(this) 的值將是 ($("button")) 對象
       // 因為這個button對象調用了 click () 方法
       console.log ($ (this).prop ("name"));
       });
      上面的代碼中,$(this)綁定到了button對象,因為jquery庫將$(this)綁定到調用點擊事件的對象。

       

      this中存在的最大的問題

      this是沒有被指定值的,直到有一個對象調用了this所在的這個函數(我們暫且給它一個稱號:this Function)。

      也就是說,只有當有一個對象調用了this Function之后,this Fuction中的this才被指定!在大多數情況下,this Function被調用之后,this都會被指定一個值,但是,也有少數的情況下this是沒有值的,這個問題我們將在后面進一步探討。

       

      全局作用域(global scope)中的this

      當一段代碼在瀏覽器中執行時,所有的全局變量和函數都是在“window”對象上定義的。因此,當”this”被用在全局函數中是,他指定的值是”window”對象。我們來看下面一段代碼:

      var firstName = "Peter",
       lastName = "Ally";
       
       function showFullName () {
       // "this" inside this function will have the value of the window object
       // because the showFullName () function is defined in the global scope, just like the firstName and lastName
       console.log (this.firstName + " " + this.lastName);
       }
       
       var person = {
       firstName :"Penelope",
       lastName :"Barrymore",
       showFullName:function () {
       // "this" on the line below refers to the person object, because the showFullName function will be invoked by person object.
       console.log (this.firstName + " " + this.lastName);
       }
       }
       
       showFullName (); // Peter Ally
       
       // window is the object that all global variables and functions are defined on, hence:
       window.showFullName (); // Peter Ally
       
       // "this" inside the showFullName () method that is defined inside the person object still refers to the person object, hence:
       person.showFullName (); // Penelope Barrymore

       

      解決回調函數中的this問題

      當包含this的回調函數作為參數傳遞時我們會遇到這樣這個問題:

      // We have a simple object with a clickHandler method that we want to use when a button on the page is clicked
       var user = {
       name:"zhouquan",
       age:21,
       clickHandler:function (event) {
       console.log (this.name + " " + this.age);
       }
       }
       
       // The button is wrapped inside a jQuery $ wrapper, so it is now a jQuery object
       // And the output will be undefined because there is no data property on the button object
       $("button").click (user.clickHandler); //undefined

      在上面的代碼中,我們知道$(“button”)是一個對象,”user.clickHandler”作為click()方法的回調函數。user.clickHandler方法中的this不再是指向user對象,它現在指向的是調用點擊事件的這個button對象。即使我們是使用“user.clickHandler”來調用clickHandler方法,但是clickHandler()方法是在button對象作為上下文(Context)的環境中運行的,所以,this指向的是button對象。

      從這一點上我們可以看出,當上下文(Context)改變--當我們在其他的對象上執行一個方法。“this”所指向的不在是以前的那個對象,而是現在調用這個方法的新的對象。

      為了解決這個問題,我們可以使用apply, call和bind的方法來指定“this”所指向的對象。所以上面代碼的最后一行只需改為:

      $("button").click (user.clickHandler.bind (user)); //zhouquan 21

       

      解決閉包(closure)中的this問題

      另外一種容易讓我們感到困擾的是當我們使用了一個內部函數(閉包)的時候。首先我們應該明確的一點就是:閉包中不能通過“this”關鍵字來訪問外邊函數的this變量,因為閉包中的this他指向的window對象。來看一個例子:

      var user = {
       country: "china",
       data:[
       {name:"ZhouYi", age:21},
       {name:"ZhouEr", age:22}
       ],
       
       clickHandler:function(){
       //在這個作用域中使用this是OK的,他指向的是user對象
       this.data.forEach(function(person){
       //但是這個內部函數的this不再指向user對象
       
       console.log("What is This referring to? " + this); //Object Window
       
       console.log(person.name + " is come from " + this.country); 
       //ZhouYi is come from undefined
       //ZhouEr is come from undefined
       })
       }
      };
      user.clickHandler();
      內部函數的this不能訪問外部函數的this,所以內部函數的this就指向了全局window對象。為了解決這個問題,我們一般都是采用中間變量來保存外部函數的this:
      clickHandler:function(){
       //在這個作用域中使用this是OK的,他指向的是user對象
       //我們定義一個theUserObj來保存this的值
       var theUserObj = this;
       this.data.forEach(function(person){
       //現在我們再用theUserObj來訪問user對象的屬性就沒問題了
       console.log(person.name + " is come from " + theUserObj.country); 
       //ZhouYi is come from china
       //ZhouEr is come from china
       })
       }
      上面的代碼中,我們用一個中間變量“theUserObj”來保存外部函數的this,以便在forEach內部函數中可以通過它來調用user對象的屬性。中間變量叫什么名字取決于你自己,大部分同學喜歡用“that”,個人覺得這個不夠形象,所以我喜歡用theUserObj這種一看就明白的詞。

       

      解決方法作為變量進行傳遞時的this問題

      當我們把一個對象里面的函數作為參數傳遞給另外一個對象時,this所指定的對象往往會超出我們的想象,來看個例子吧:

      var data = [
      {name: "ZhouYi", age:21},
      {name: "ZhouEr", age:22}
      ];
       
      var user = {
       //這里的data屬性是屬于user對象的
       data :[
       {name:"ZhouYi", age: 31},
       {name:"ZhouEr", age: 32}
       ],
       showData:function(){
       console.log(this.data[0].name + " " + this.data[0].age) ;
       }
      }
       
      //把user.showData賦值給一個變量
      var showUserData = user.showData;
      //當我們執行這個showUserData函數時,輸出的數據來自全局的data(最外層定義的),而不是來自與user對象中的data.
      showUserData(); //ZhouYi 21
      解決這個問題的方式跟前面提到的解決回調函數中的this問題類似,我們還是采用apply, call和bind的方法來綁定指定的上下文,也就是this該指向哪個對象。
      var showUserDate = user.showData.bind(user);

       

      解決方法借用中的this問題

      何謂方法調用?打個簡單的比方,有兩個對象A和B,A、B有相同的屬性,但是B比A還多了一個方法,這個方法是對B中的數據進行處理,現在我們想把B這種方法也給A用用:

      var gameController = {
       scores : [20, 34, 55, 46, 77],
       avgScore: null,
       players:[
       {name:"Tommy", playerID:987, age:23},
       {name:"Pau", playerID: 87, age: 33}
       ]
      }
       
      var appController = {
       scores: [900, 845, 809, 950],
       avgScore: null,
       avg: function(){
       var sumOfSores = this.scores.reduce(function(prev, cur, index, array){
       return prev + cur;
       });
       
       this.avgScore = sumOfSores /this.scores.length;
       }
       
      }
      //由于avg()是被appController調用的,所以avg中的this指向的是appController對象。
      gameController.avgScore = appController.avg();
      console.log(gameController.avgScore); //undefined
      如何解決這個問題呢? 為了讓appController.avg()指向gameController對象,我們可以使用apply()方法:
       // Note that we are using the apply () method, so the 2nd argument has to be an array—the arguments to pass to the appController.avg () method.
       appController.avg.apply (gameController, gameController.scores);
       
       // The avgScore property was successfully set on the gameController object, even though we borrowed the avg () method from the appController object
       console.log (gameController.avgScore); // 46.4
       
       // appController.avgScore is still null; it was not updated, only gameController.avgScore was updated
       console.log (appController.avgScore); // null
      注意我們這里使用了兩個參數,第一個參數表示this的上下文,也就是this所指向的對象;第二個參數表示要進行運算的數據。當然啦,我們還可以通過這種方式達到同樣的效果:

      gameController.avg = appController.avg;
      gameController.avg();
      
      

       

      小結

      希望我寫的這些東西可以給你帶來一些幫助,如果你覺得哪個地方存在不足,請你在評論處提出來,我將及時完善,免得誤導后面的同學;如果你覺得這篇文章講得還可以,請幫我推薦給更多的有需要的同學閱讀,謝謝!

      
      

       

       

      參考資料:http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

      posted @ 2013-10-18 16:48  CodingMonkey  閱讀(1898)  評論(4)    收藏  舉報
      主站蜘蛛池模板: 乱人伦中文字幕成人网站在线| 午夜免费无码福利视频麻豆| 一日本道伊人久久综合影| 日韩成人高精品一区二区| 亚洲毛片多多影院| 欧美性xxxxx极品| 国产午夜伦伦午夜伦无码| 女同亚洲精品一区二区三| 国产日韩av二区三区| yy111111少妇无码影院| 国产精品一区二区久久岳| 亚洲人成电影网站 久久影视| 欧美深度肠交惨叫| 久久精品国产亚洲av高| 日韩精品中文字幕人妻| 枣阳市| 最新午夜男女福利片视频| 中文字幕精品亚洲无线码二区| 广饶县| 国产亚洲精品综合一区二区| 正在播放酒店约少妇高潮| 综合偷自拍亚洲乱中文字幕| 最新偷拍一区二区三区| √天堂中文www官网在线| 亚洲av综合久久成人网| 电影在线观看+伦理片| 国产成a人亚洲精v品无码性色 | 久久中文字幕无码专区| 一本久道久久综合中文字幕| 国产成人亚洲综合图区| 精选国产av精选一区二区三区| 99久久国产精品无码| 久操资源站| 99久久无码一区人妻a黑| 精品一日韩美女性夜视频| www内射国产在线观看| 国产精品一区二区在线蜜芽tv| 日韩AV高清在线看片| 日韩加勒比一本无码精品| 日韩精品一二区在线观看| 日本中文一区二区三区亚洲|