<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【javascript】函數(shù)中的this的四種綁定形式 — 大家準備好瓜子,我要講故事啦~~

          共 5246字,需瀏覽 11分鐘

           ·

          2020-11-27 15:24

          ?是新朋友嗎?記得先關注我哦~


          目錄

          • this的默認綁定

          • this的隱式綁定

            • 隱式綁定下,作為對象屬性的函數(shù),對于對象來說是獨立的

            • 在一串對象屬性鏈中,this綁定的是最內(nèi)層的對象

          • this的顯式綁定:(call和bind方法)

          • new綁定

          ?

          正文

          javascript中的this和函數(shù)息息相關,所以今天,我就給大家詳細地講述一番:javascript函數(shù)中的this

          ?

          一談到this,很多讓人暈暈乎乎的抽象概念就跑出來了,這里我就只說最核心的一點——函數(shù)中的this總指向調(diào)用它的對象,接下來的故事都將圍繞這一點展開

          ?

          (提醒前排的筒子們準備好茶水和西瓜,我要開始講故事啦!!)

          ?

          【故事】有一個年輕人叫"迪斯"(this),有一天,迪斯不小心穿越到一個叫?“伽瓦斯克利”(javascript)的 異世界,此時此刻迪斯身無分文, 他首先要做的事情就是——找到他的住宿的地方——調(diào)用函數(shù)的對象

          ?

          this的默認綁定

          【故事——線路1】如果迪斯(this)直到天黑前都沒有找到能收留自己的住所,他眼看就要過上非洲難民的生活, 這時候,一位樂善好施的魔法師村長——window救世主一般地出現(xiàn)了:先住在我家吧!

          ?

          【正文】

          當一個函數(shù)沒有明確的調(diào)用對象的時候,也就是單純作為獨立函數(shù)調(diào)用的時候,將對函數(shù)的this使用默認綁定:綁定到全局的window對象

          function fire () {     console.log(this === window)}fire(); // 輸出true

          上面的例子我相信對大多數(shù)人都很簡單,但有的時候我們把例子變一下就會具有迷惑性:

          function fire () {  // 我是被定義在函數(shù)內(nèi)部的函數(shù)哦!     function innerFire() {  console.log(this === window)      }     innerFire(); // 獨立函數(shù)調(diào)用}fire(); // 輸出true

          函數(shù) innerFire在一個外部函數(shù)fire里面聲明且調(diào)用,那么它的this是指向誰呢?仍然是window

          ?

          許多人可能會顧慮于fire函數(shù)的作用域?qū)nnerFire的影響,但我們只要抓住我們的理論武器——沒有明確的調(diào)用對象的時候,將對函數(shù)的this使用默認綁定:綁定到全局的window對象,便可得正確的答案了

          ?

          下面這個加強版的例子也是同樣的輸出true

          var obj = {   fire: function () {       function innerFire() {          console.log(this === window)        }        innerFire();   // 獨立函數(shù)調(diào)用     }}obj.fire(); //輸出 true

          【注意】在這個例子中, obj.fire()的調(diào)用實際上使用到了this的隱式綁定,這就是下面我要講的內(nèi)容,這個例子我接下來還會繼續(xù)講解

          ?

          【總結】 凡事函數(shù)作為獨立函數(shù)調(diào)用,無論它的位置在哪里,它的行為表現(xiàn),都和直接在全局環(huán)境中調(diào)用無異

          ?

          this的隱式綁定

          【故事——線路2】 迪斯(this)穿越來異世界“伽瓦斯克利”(javascript)的時候,剛好身上帶了一些錢,于是他找到一個旅館住宿了下來

          ?

          ?

          函數(shù)被一個對象“包含”的時候,我們稱函數(shù)的this被隱式綁定到這個對象里面了,這時候,通過this可以直接訪問所綁定的對象里面的其他屬性,比如下面的a屬性

          var obj = {     a: 1,      fire: function () {           console.log(this.a)        }}obj.fire(); // 輸出1

          現(xiàn)在我們需要對平常司空見慣的的代碼操作做一些更深的思考,首先,下面的這兩段代碼達到的效果是相同的:

          // 我是第一段代碼function fire () {      console.log(this.a)}
          var obj = { a: 1, fire: fire }obj.fire(); // 輸出1
          // 我是第二段代碼var obj = { a: 1, fire: function () { console.log(this.a) }}obj.fire(); // 輸出1?

          fire函數(shù)并不會因為它被定義在obj對象的內(nèi)部和外部而有任何區(qū)別,也就是說在上述隱式綁定的兩種形式下,fire通過this還是可以訪問到obj內(nèi)的a屬性,這告訴我們:

          ?

          1.? this是動態(tài)綁定的,或者說是在代碼運行期綁定而不是在書寫期

          2.? 函數(shù)于對象的獨立性, this的傳遞丟失問題

          ?

          (下面的描述可能帶有個人的情感傾向而顯得不太嚴謹,但這是因為我希望閱讀者盡可能地理解我想表達的意思)


          隱式綁定下,作為對象屬性的函數(shù),對于對象來說是獨立的

          基于this動態(tài)綁定的特點,寫在對象內(nèi)部,作為對象屬性的函數(shù),對于這個對象來說是獨立的。(函數(shù)并不被這個外部對象所完全擁有”)

          ?

          我想表達的意思是:在上文中,函數(shù)雖然被定義在對象的內(nèi)部中,但它和“在對象外部聲明函數(shù),然后在對象內(nèi)部通過屬性名稱的方式取得函數(shù)的引用”,這兩種方式在性質(zhì)上是等價的而不僅僅是效果上

          ?

          定義在對象內(nèi)部的函數(shù)只是“恰好可以被這個對象調(diào)用”而已,而不是“生來就是為這個對象所調(diào)用的”

          ?

          借用下面的隱式綁定中的this傳遞丟失問題來說明:

          var obj = {      a: 1,    // a是定義在對象obj中的屬性   1      fire: function () {   console.log(this.a)        }      }
          var a = 2; // a是定義在全局環(huán)境中的變量 2var fireInGrobal = obj.fire; fireInGrobal(); // 輸出 2

          上面這段簡單代碼的有趣之處在于:這個于obj中的fire函數(shù)的引用( fireInGrobal)在調(diào)用的時候,行為表現(xiàn)(輸出)完全看不出來它就是在obj內(nèi)部定義的,其原因在于:我們隱式綁定的this丟失了!!從而 fireInGrobal調(diào)用的時候取得的this不是obj,而是window


          上面的例子稍微變個形式就會變成一個可能困擾我們的bug:

          var a = 2;var obj = {    a: 1,    // a是定義在對象obj中的屬性    fire: function () {          console.log(this.a)     }}  function otherFire (fn) {     fn();}  otherFire(obj.fire); // 輸出2

          在上面,我們的關鍵角色是otherFire函數(shù),它接受一個函數(shù)引用作為參數(shù),然后在內(nèi)部直接調(diào)用,但它做的假設是參數(shù)fn仍然能夠通過this去取得obj內(nèi)部的a屬性,但實際上, this對obj的綁定早已經(jīng)丟失了,所以輸出的是全局的a的值(2),而不是obj內(nèi)部的a的值(1)


          在一串對象屬性鏈中,this綁定的是最內(nèi)層的對象

          在隱式綁定中,如果函數(shù)調(diào)用位置是在一串對象屬性鏈中,this綁定的是最內(nèi)層的對象。如下所示:

          var obj = {      a: 1,      obj2: {           a: 2,           obj3: {                a:3,                getA: function () {                    console.log(this.a)                    }           }       }}
          obj.obj2.obj3.getA(); // 輸出3

          ?

          this的顯式綁定:(call和bind方法)

          【故事——線路3】 迪斯(this)穿越來異世界“伽瓦斯克利”(javascript),經(jīng)過努力的打拼,積累了一定的財富,于是他買下了自己的房子

          ?

          上面我們提到了this的隱式綁定所存在的this綁定丟失的問題,也就是對于 “ fireInGrobal = obj.fire”

          fireInGrobal調(diào)用和obj.fire調(diào)用的結果是不同的因為這個函數(shù)賦值的過程無法把fire所綁定的this也傳遞過去。這個時候,call函數(shù)就派上用場了

          ?

          call的基本使用方式:fn.call(object)

          fn是你調(diào)用的函數(shù),object參數(shù)是你希望函數(shù)的this所綁定的對象。

          fn.call(object)的作用:

          1.即刻調(diào)用這個函數(shù)(fn)

          2.調(diào)用這個函數(shù)的時候函數(shù)的this指向object對象

          ?

          例子:

          var obj = {      a: 1,    // a是定義在對象obj中的屬性      fire: function () {         console.log(this.a)      }}
          var a = 2; // a是定義在全局環(huán)境中的變量 var fireInGrobal = obj.fire;fireInGrobal(); // 輸出2fireInGrobal.call(obj); // 輸出1?

          原本丟失了與obj綁定的this參數(shù)的fireInGrobal再次重新把this綁回到了obj

          ?

          但是,我們其實不太喜歡這種每次調(diào)用都要依賴call的方式,我們更希望:能夠一次性 返回一個this被永久綁定到obj的fireInGrobal函數(shù),這樣我們就不必每次調(diào)用fireInGrobal都要在尾巴上加上call那么麻煩了。

          ?

          怎么辦呢?聰明的你一定能想到,在fireInGrobal.call(obj)外面包裝一個函數(shù)不就可以了嘛!

          var obj = {      a: 1,    // a是定義在對象obj中的屬性      fire: function () {        console.log(this.a)      }}
          var a = 2; // a是定義在全局環(huán)境中的變量 var fn = obj.fire;var fireInGrobal = function () { fn.call(obj) //硬綁定}
          fireInGrobal(); // 輸出1

          ?

          如果使用bind的話會更加簡單

          var fireInGrobal = function () {    fn.call(obj)   //硬綁定}
          可以簡化為:var fireInGrobal = fn.bind(obj);

          ?

          call和bind的區(qū)別是:在綁定this到對象參數(shù)的同時:

          ?

          1.call將立即執(zhí)行該函數(shù)

          2.bind不執(zhí)行函數(shù),只返回一個可供執(zhí)行的函數(shù)

          ?

          【其他】:至于apply,因為除了使用方法,它和call并沒有太大差別,這里不加贅述

          ?

          在這里,我把顯式綁定和隱式綁定下,函數(shù)和“包含”函數(shù)的對象間的關系比作買房和租房的區(qū)別

          ?

          因為this的緣故

          ?

          在隱式綁定下:函數(shù)和只是暫時住在“包含對象“的旅館里面,可能過幾天就又到另一家旅館住了

          在顯式綁定下:函數(shù)將取得在“包含對象“里的永久居住權,一直都會”住在這里“

          ?

          new綁定

          【故事】 迪斯(this)組建了自己的家庭,并生下多個孩子(通過構造函數(shù)new了許多個對象)

          執(zhí)行new操作的時候,將創(chuàng)建一個新的對象,并且將構造函數(shù)的this指向所創(chuàng)建的新對象?


          function foo (a) {     this.a = a;}
          var a1 = new foo (1);var a2 = new foo (2);var a3 = new foo (3);var a4 = new foo (4);
          console.log(a1.a); // 輸出1console.log(a2.a); // 輸出2console.log(a3.a); // 輸出3console.log(a4.a); // 輸出4

          謝謝大家哦!!

          ?

          【完】


          源自:https://www.cnblogs.com/penghuwan/p/7356210.html

          聲明:文章著作權歸作者所有,如有侵權,請聯(lián)系小編刪除。

          感謝 · 轉(zhuǎn)發(fā)歡迎大家留言

          掃碼關注公眾號,訂閱更多精彩內(nèi)容。



          你點的每個贊,我都認真當成了喜歡
          瀏覽 28
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本午夜影院 | 啊啊啊啊啊在线免费观看 | 三级黄色成人网站国产操花 | 日韩特级毛片在线视频 | 国产美国黄色毛片 |