成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

你不知道的this

terasum / 1415人閱讀

摘要:本內(nèi)容來(lái)自你不知道的上卷,做了簡(jiǎn)單的總結(jié)。如果不使用這段代碼該如何寫呢那就需要給和顯示傳入一個(gè)上下文對(duì)象對(duì)比發(fā)現(xiàn)提供了額一種更優(yōu)雅的方式來(lái)隱式傳遞一個(gè)對(duì)象引用。四總結(jié)隨著你使用的模式越來(lái)越復(fù)雜,顯式傳遞上下文對(duì)象會(huì)讓代碼變得越來(lái)越混亂。

本內(nèi)容來(lái)自《你不知道的JavaScript(上卷)》,做了簡(jiǎn)單的總結(jié)

this關(guān)鍵字是javascript最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在所有的函數(shù)作用域中。但是即使是非常有經(jīng)驗(yàn)的javascript開(kāi)發(fā)者也很難說(shuō)出他到底指向什么。本節(jié)將分三個(gè)部分講解javascript中的this:

為什么要使用this

兩種常見(jiàn)的對(duì)于this的誤解

this到底是什么

一、為什么要使用this

在書(shū)中通過(guò)兩段代碼的對(duì)比來(lái)說(shuō)明為什么要使用this。第一段代碼如下:這段代碼在不同的上下問(wèn)對(duì)象(me和you)中重復(fù)使用函數(shù)identify()和speak(),不用針對(duì)不同的對(duì)象編寫不同版本的函數(shù)。

function identify(){
      return this.name.toUpperCase();
  }
  function speak(){
      var greeting = "hello, I am " + identify.call(this);
      console.log(greeting);
  }
  var me = {
      name: "zhou"
  }
  var you = {
      name: "reader"
  }
  identify.call(me); //ZHOU
  identify.call(you); //READER
  speak.call(me); // hello, I am ZHOU
  speak.call(you); // hello, I am READER

如果不使用this, 這段代碼該如何寫呢?那就需要給identify()和speak()顯示傳入一個(gè)上下文對(duì)象

      function identify(cxt){
          return cxt.name.toUpperCase();
      }
      function speak(cxt){
          var greeting = "hello, I am " + identify(cxt);
          console.log(greeting);
      }
      identify(you); //READER
      speak(me); //hello, I am ZHOU

對(duì)比發(fā)現(xiàn):this提供了額一種更優(yōu)雅的方式來(lái)隱式“傳遞”一個(gè)對(duì)象引用。因?yàn)?,隨著你使用的模式越來(lái)越復(fù)雜,顯式傳遞上下文對(duì)象會(huì)讓代碼變得越來(lái)越混亂。因此,通過(guò)使用this可以將API設(shè)計(jì)的更加簡(jiǎn)潔并且易于復(fù)用。

二、兩種常見(jiàn)的對(duì)于this的誤解 誤解1.指向函數(shù)自身

把this理解為指向函數(shù)自身,這個(gè)推斷從英語(yǔ)語(yǔ)法角度是說(shuō)的通的。
常見(jiàn)的在函數(shù)內(nèi)部引用自身的情況有:遞歸或者是一個(gè)在第一次被調(diào)用后自己接觸綁定的事件處理器。 JavaScript的新手開(kāi)發(fā)者(比如說(shuō)我)通常認(rèn)為:既然可以把函數(shù)看作一個(gè)對(duì)象,那就可以在調(diào)用函數(shù)時(shí)存儲(chǔ)狀態(tài)(屬性的值)。
現(xiàn)在我們來(lái)分析這個(gè)模式,讓大家看到this并不像所想的那樣指向函數(shù)本身。下面這段代碼,我們想要記錄函數(shù)foo被調(diào)用的次數(shù):

      function foo(num){
          console.log("foo: " + num);
          this.count++; //記錄foo被調(diào)用的次數(shù)
      }
      foo.count = 0;
      
      for(var i=0; i<10; i++){
          if(i > 5){
              foo(i)
          }
      }
       // foo: 6
       // foo: 7
       // foo: 8
       // foo: 9
      
       console.log(foo.count); // 0  為什么會(huì)是0呢?

foo()函數(shù)中的console.log語(yǔ)句產(chǎn)生了4條輸出,證明foo()確實(shí)被調(diào)用了4次,但foo.count仍然是0,所以,僅從字面上來(lái)理解,this指向函數(shù)自身是錯(cuò)誤的。那么,問(wèn)題的原因是什么呢?
foo()函數(shù)是在全局作用域下執(zhí)行的,this在這段代碼中其實(shí)指向window,并且這段代碼在無(wú)意中創(chuàng)建了一個(gè)全局變量count,他的值為NaN。
那么,遇到這樣的問(wèn)題許多的開(kāi)發(fā)者(包括我),不會(huì)深入的思考為什么this的行為和預(yù)期的不一致,也不會(huì)回答那些很難解決,但非常重要的問(wèn)題。這里提供了三種解決這個(gè)問(wèn)題的方法,其中前兩種方法回避了this的含義和工作原理。代碼如下:

方法一 運(yùn)用作用域(詞法作用域)方法,該方法解決了我們遇到的問(wèn)題,但是卻沒(méi)有直面this。

     function foo(num){
          console.log("foo: " + num);
          data.count++; //記錄foo被調(diào)用的次數(shù)
      }
      var data ={
       count: 0
      };
      
      for(var i=0; i<10; i++){
          if(i > 5){
              foo(i);
          }
      }
       // foo: 6
       // foo: 7
       // foo: 8
       // foo: 9
      console.log(data.count);// 4

方法二 創(chuàng)建一個(gè)指向函數(shù)對(duì)象的詞法標(biāo)識(shí)符(變量)來(lái)引用它。同樣該方法仍舊回避了this的問(wèn)題。

    function foo(num){
          console.log("foo: " + num);
          foo.count++; // foo指向它自身
      }
      foo.count = 0;
      for(var i=0; i<10; i++){
          if(i > 5){
              foo(i);
          }
      }
       // foo: 6
       // foo: 7
       // foo: 8
       // foo: 9
      console.log(foo.count);// 4

方法三 既然我們知道this在foo函數(shù)執(zhí)行時(shí)指向了別處,那么我們需要做的就是強(qiáng)制this指向foo函數(shù).

function foo(num){
          console.log("foo: " + num);
          this.count++;
      }
      foo.count = 0;
      for(var i=0; i<10; i++){
          if(i > 5){
              foo.call(foo, i); //使用call()可以確保this指向函數(shù)本身
          }
      }
       // foo: 6
       // foo: 7
       // foo: 8
       // foo: 9
      console.log(foo.count);// 4

這次我們從this的角度解決了問(wèn)題。

誤解2.指向函數(shù)作用域

第二種常見(jiàn)的誤解是:this指向函數(shù)作用域。這個(gè)問(wèn)題有點(diǎn)復(fù)雜,因?yàn)樵谀撤N情況下它是正確的,但在其他情況下他卻是錯(cuò)誤的。
但一定要明白,this在任何情況下都不指向函數(shù)的作用域,在javascript內(nèi)部作用域和對(duì)象確實(shí)很相似,可見(jiàn)的標(biāo)識(shí)符都是他的屬性,但作用域“對(duì)象”無(wú)法通過(guò)JavaScript代碼訪問(wèn),它存在于JavaScript引擎內(nèi)部
在文中給出了這樣一段代碼:

    function foo(){
         var a = 2;
         this.bar();
    }
    function bar(){
        console.log(this.a);
    }
    foo(); // ReferenceError: a is not defined

這段代碼試圖通過(guò)this聯(lián)通foo()和bar()的詞法作用域,從而讓bar()可以訪問(wèn)foo()作用域的變量a。but it"s impossible!

三、this到底是個(gè)什么玩意?

通過(guò)排除以上種種的誤解,我們可以得出以下結(jié)論:

this是在運(yùn)行時(shí)進(jìn)行綁定的,并不是在編寫時(shí)綁定的。

this的綁定和函數(shù)聲明的位置沒(méi)有關(guān)系,只取決于函數(shù)的調(diào)用方式。

具體細(xì)節(jié)是:當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(也稱執(zhí)行上下文(context))。這個(gè)記錄會(huì)包含一些信息,比如: 函數(shù)在哪里被調(diào)用(調(diào)用棧), 函數(shù)的調(diào)用方式, 傳入的參數(shù)等,而this就是這個(gè)記錄的一個(gè)屬性,會(huì)在函數(shù)執(zhí)行過(guò)程中被用到。

四、總結(jié)

隨著你使用的模式越來(lái)越復(fù)雜,顯式傳遞上下文對(duì)象會(huì)讓代碼變得越來(lái)越混亂。因此,通過(guò)使用this隱式傳遞可以將API設(shè)計(jì)的更加簡(jiǎn)潔并且易于復(fù)用

this既不指向函數(shù)自身,也不指向函數(shù)的作用域。

this實(shí)際上是函數(shù)被調(diào)用時(shí)發(fā)生的綁定,它的指向完全取決于函數(shù)在哪里被調(diào)用

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78912.html

相關(guān)文章

  • 你不知道Virtual DOM(五):自定義組件

    摘要:現(xiàn)在流行的前端框架都支持自定義組件,組件化開(kāi)發(fā)已經(jīng)成為提高前端開(kāi)發(fā)效率的銀彈。二對(duì)自定義組件的支持要想正確的渲染組件,第一步就是要告訴某個(gè)標(biāo)簽是自定義組件。下面的例子里,就是一個(gè)自定義組件。解決了識(shí)別自定義標(biāo)簽的問(wèn)題,下一步就是定義標(biāo)簽了。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...

    lk20150415 評(píng)論0 收藏0
  • 你不知道Virtual DOM(六):事件處理&異步更新

    摘要:如果列表是空的,則存入組件后將異步刷新任務(wù)加入到事件循環(huán)當(dāng)中。四總結(jié)本文基于上一個(gè)版本的代碼,加入了事件處理功能,同時(shí)通過(guò)異步刷新的方法提高了渲染效率。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的兩大前端框架,React和Vue,都不約而同的借助Virtual DO...

    caozhijian 評(píng)論0 收藏0
  • 你不知道JavaScript》 (下) 閱讀摘要

    摘要:本書(shū)屬于基礎(chǔ)類書(shū)籍,會(huì)有比較多的基礎(chǔ)知識(shí),所以這里僅記錄平常不怎么容易注意到的知識(shí)點(diǎn),不會(huì)全記,供大家和自己翻閱不錯(cuò),下冊(cè)的知識(shí)點(diǎn)就這么少,非常不推介看下冊(cè)上中下三本的讀書(shū)筆記你不知道的上讀書(shū)筆記你不知道的中讀書(shū)筆記你不知道的下讀書(shū)筆記第三 本書(shū)屬于基礎(chǔ)類書(shū)籍,會(huì)有比較多的基礎(chǔ)知識(shí),所以這里僅記錄平常不怎么容易注意到的知識(shí)點(diǎn),不會(huì)全記,供大家和自己翻閱; 不錯(cuò),下冊(cè)的知識(shí)點(diǎn)就這么少,非...

    Jacendfeng 評(píng)論0 收藏0
  • 你不知道javascript》筆記_this

    下一篇:《你不知道的javascript》筆記_對(duì)象&原型 寫在前面 上一篇博客我們知道詞法作用域是由變量書(shū)寫的位置決定的,那this又是在哪里確定的呢?如何能夠精準(zhǔn)的判斷this的指向?這篇博客會(huì)逐條闡述 書(shū)中有這樣幾句話: this是在運(yùn)行時(shí)進(jìn)行綁定的,并不是在編寫時(shí)綁定,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件this的綁定和函數(shù)聲明的位置沒(méi)有任何關(guān)系,只取決于函數(shù)的調(diào)用方式當(dāng)一個(gè)函數(shù)被調(diào)用時(shí)...

    cpupro 評(píng)論0 收藏0
  • 你不知道JavaScript》 (上) 閱讀摘要

    摘要:但是如果非全局的變量如果被遮蔽了,無(wú)論如何都無(wú)法被訪問(wèn)到。但是如果引擎在代碼中找到,就會(huì)完全不做任何優(yōu)化。結(jié)構(gòu)的分句中具有塊級(jí)作用域。第四章提升編譯器函數(shù)聲明會(huì)被提升,而函數(shù)表達(dá)式不會(huì)被提升。 本書(shū)屬于基礎(chǔ)類書(shū)籍,會(huì)有比較多的基礎(chǔ)知識(shí),所以這里僅記錄平常不怎么容易注意到的知識(shí)點(diǎn),不會(huì)全記,供大家和自己翻閱; 上中下三本的讀書(shū)筆記: 《你不知道的JavaScript》 (上) 讀書(shū)筆記...

    FingerLiu 評(píng)論0 收藏0
  • 你不知道javascript (1) --- this

    摘要:的定義執(zhí)行上下文。這本書(shū)也是舉了好幾個(gè)例子來(lái)說(shuō)明,這句話的含義。我個(gè)人也認(rèn)為,不通過(guò)代碼,非常難說(shuō)明問(wèn)題。所以,修改的是全局的,并不是自身的。 this 先說(shuō)明一下,this是我JavaScript的盲區(qū),寫這篇文章,就是為了讓自己能重新認(rèn)識(shí)this,并且搞清楚,js里面的this,到底是什么。 這個(gè)系列主要是記錄我自己看《你不知道的JavaScript》這本書(shū)的筆記。 this的定義...

    Corwien 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<