<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

        • JavaScript之this指針深入詳解

          2016-11-9    藍(lán)藍(lán)設(shè)計(jì)的小編

          如果您想訂閱本博客內(nèi)容,每天自動(dòng)發(fā)到您的郵箱中,?請(qǐng)點(diǎn)這里 

          javascript中的this含義非常豐富,它可以是全局對(duì)象,當(dāng)前對(duì)象或者是任意對(duì)象,這都取決于函數(shù)的調(diào)用方式。函數(shù)有以下幾種調(diào)用方式:作為對(duì)象方法調(diào)用、作為函數(shù)調(diào)用、作為構(gòu)造函數(shù)調(diào)用、apply或call調(diào)用。

          對(duì)象方法調(diào)用

          作為對(duì)象方法調(diào)用的時(shí)候,this會(huì)被綁定到該對(duì)象。

          var point = { 
           x : 0, 
           y : 0, 
           moveTo : function(x, y) { 
               this.x = this.x + x; 
               this.y = this.y + y; 
               } 
           }; 
          
           point.moveTo(1, 1)//this 綁定到當(dāng)前對(duì)象,即 point 對(duì)象

          這里我想強(qiáng)調(diào)一點(diǎn)內(nèi)容,就是this是在函數(shù)執(zhí)行的時(shí)候去獲取對(duì)應(yīng)的值,而不是函數(shù)定義時(shí)。即使是對(duì)象方法調(diào)用,如果該方法的函數(shù)屬性以函數(shù)名的形式傳入別的作用域,也會(huì)改變this的指向。我舉一個(gè)例子:

          var a = {
              aa : 0,
              bb : 0,
              fun : function(x,y){
                  this.aa = this.aa + x;
                  this.bb = this.bb + y;
              }
          };
          var aa = 1;
          var b = {
              aa:0,
              bb:0,
              fun : function(){return this.aa;}
          }   
          a.fun(3,2);
          document.write(a.aa);//3,this指向?qū)ο蟊旧?document.write(b.fun());//0,this指向?qū)ο蟊旧?(function(aa){//注意傳入的是函數(shù),而不是函數(shù)執(zhí)行的結(jié)果
              var c = aa();
              document.write(c);//1 , 由于fun在該處執(zhí)行,導(dǎo)致this不再指向?qū)ο蟊旧恚沁@里的window
          })(b.fun);

          這樣就明白了吧。這是一個(gè)容易混淆的地方。

          函數(shù)調(diào)用

          函數(shù)也可以直接被調(diào)用,這個(gè)時(shí)候this被綁定到了全局對(duì)象。

           var x = 1;
            function test(){
              this.x = 0;
            }
            test();
            alert(x); //0

          但這樣就會(huì)出現(xiàn)一些問(wèn)題,就是在函數(shù)內(nèi)部定義的函數(shù),其this也會(huì)指向全局,而和我們希望的恰恰相反。代碼如下:

          var point = { 
           x : 0, 
           y : 0, 
           moveTo : function(x, y) { 
               // 內(nèi)部函數(shù)
               var moveX = function(x) { 
               this.x = x;//this 綁定到了全局
              }; 
              // 內(nèi)部函數(shù)
              var moveY = function(y) { 
              this.y = y;//this 綁定到了全局
              }; 
          
              moveX(x); 
              moveY(y); 
              } 
           }; 
           point.moveTo(1, 1); 
           point.x; //==>0 
           point.y; //==>0 
           x; //==>1 
           y; //==>1

          我們會(huì)發(fā)現(xiàn)不但我們希望的移動(dòng)呢效果沒(méi)有完成,反而會(huì)多出兩個(gè)全局變量。那么如何解決呢?只要要進(jìn)入函數(shù)中的函數(shù)時(shí)將this保存到一個(gè)變量中,再運(yùn)用該變量即可。代碼如下:

          var point = { 
           x : 0, 
           y : 0, 
           moveTo : function(x, y) { 
                var that = this; 
               // 內(nèi)部函數(shù)
               var moveX = function(x) { 
               that.x = x; 
               }; 
               // 內(nèi)部函數(shù)
               var moveY = function(y) { 
               that.y = y; 
               } 
               moveX(x); 
               moveY(y); 
               } 
           }; 
           point.moveTo(1, 1); 
           point.x; //==>1 
           point.y; //==>1

          構(gòu)造函數(shù)調(diào)用

          在javascript中自己創(chuàng)建構(gòu)造函數(shù)時(shí)可以利用this來(lái)指向新創(chuàng)建的對(duì)象上。這樣就可以避免函數(shù)中的this指向全局了。

           var x = 2;
            function test(){
              this.x = 1;
            }
            var o = new test();
            alert(x); //2

          apply或call調(diào)用

          這兩個(gè)方法可以切換函數(shù)執(zhí)行的上下文環(huán)境,也就是改變this綁定的對(duì)象。apply和call比較類似,區(qū)別在于傳入?yún)?shù)時(shí)一個(gè)要求是數(shù)組,一個(gè)要求是分開(kāi)傳入。所以我們以apply為例:

          <pre name="code" class="html">var name = "window";
          
          var someone = {
              name: "Bob",
              showName: function(){
                  alert(this.name);
              }
          };
          
          var other = {
              name: "Tom"
          };   
          
          someone.showName();     //Bob
          someone.showName.apply();    //window
          someone.showName.apply(other);    //Tom

          可以看到,正常訪問(wèn)對(duì)象中方法時(shí),this指向?qū)ο蟆J褂昧薬pply后,apply無(wú)參數(shù)時(shí),this的當(dāng)前對(duì)象是全局,apply有參數(shù)時(shí),this的當(dāng)前對(duì)象就是該參數(shù)。

          箭頭函數(shù)調(diào)用

          這里需要補(bǔ)充一點(diǎn)內(nèi)容,就是在下一代javascript標(biāo)準(zhǔn)ES6中的箭頭函數(shù)的 this始終指向函數(shù)定義時(shí)的 this,而非執(zhí)行時(shí)。我們通過(guò)一個(gè)例子來(lái)理解:

          var o = {
              x : 1,
              func : function() { console.log(this.x) },
              test : function() {
                  setTimeout(function() {
                      this.func();
                  }, 100);
              }
          };
          
          o.test(); // TypeError : this.func is not a function

          上面的代碼會(huì)出現(xiàn)錯(cuò)誤,因?yàn)閠his的指向從o變?yōu)榱巳帧N覀冃枰薷纳厦娴拇a如下:

          var o = {
              x : 1,
              func : function() { console.log(this.x) },
              test : function() {
                  var _this = this;
                  setTimeout(function() {
                      _this.func(); 
                  }, 100);
              }
          };
          
          o.test();

          通過(guò)使用外部事先保存的this就行了。這里就可以利用到箭頭函數(shù)了,我們剛才說(shuō)過(guò),箭頭函數(shù)的 this始終指向函數(shù)定義時(shí)的 this,而非執(zhí)行時(shí)。所以我們將上面的代碼修改如下:

          var o = {
              x : 1,
              func : function() { console.log(this.x) },
              test : function() {
                  setTimeout(() => { this.func() }, 100);
              }
          };
          
          o.test();

          這回this就指向o了,我們還需要注意一點(diǎn)的就是這個(gè)this是不會(huì)改變指向?qū)ο蟮模覀冎纁all和apply可以改變this的指向,但是在箭頭函數(shù)中是無(wú)效的。

          var x = 1,
              o = {
                  x : 10,
                  test : () => this.x
              };
          
          o.test(); // 1
          o.test.call(o); // 依然是1

          這樣就可以明白各種情況下this綁定對(duì)象的區(qū)別了。

           

          藍(lán)藍(lán)設(shè)計(jì)m.sdgs6788.com?)是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)BS界面設(shè)計(jì)? cs界面設(shè)計(jì)? ipad界面設(shè)計(jì)? 包裝設(shè)計(jì)? 圖標(biāo)定制? 用戶體驗(yàn) 、交互設(shè)計(jì)、?網(wǎng)站建設(shè)?平面設(shè)計(jì)服務(wù) 

           

          日歷

          鏈接

          個(gè)人資料

          存檔

          91精品国产91久久综合| 人妻无码久久一区二区三区免费| Xx性欧美肥妇精品久久久久久| 久久美女网站免费| 性高朝久久久久久久久久| 无码国内精品久久人妻| 国内精品久久久久久麻豆| 一本色道久久HEZYO无码| 日本免费一区二区久久人人澡| 亚洲七七久久精品中文国产| 久久精品中文字幕久久| 国产欧美久久久精品影院| 久久99中文字幕久久| 热综合一本伊人久久精品| 久久免费小视频| 亚洲国产精品高清久久久| 久久99精品国产99久久6| 99国产精品久久久久久久成人热| 久久笫一福利免费导航| 国产真实乱对白精彩久久| 久久99精品国产| 久久久亚洲欧洲日产国码二区| 伊人色综合九久久天天蜜桃| 狠狠久久综合| 国产综合免费精品久久久| 999久久久无码国产精品| 久久综合88熟人妻| 亚洲精品乱码久久久久久自慰| 亚州日韩精品专区久久久| 久久99精品国产麻豆不卡| 精品国产91久久久久久久a | 精品熟女少妇AV免费久久| 国产午夜福利精品久久| 亚洲一本综合久久| 色综合久久综精品| 久久se这里只有精品| 久久国产热这里只有精品| 久久国产美女免费观看精品 | 亚洲国产成人久久精品影视| 国产婷婷成人久久Av免费高清| 久久久无码人妻精品无码|