this 基本概念

  1. 為什么要使用this
  2. this 的使用誤解 ( 2 種 指向誤解 )
  3. this 和詞法作用域的比較
  4. this 的指向正解
  5. this 的綁定方法( call()、apply()、bind() )

this 總是返回一個對象( fun 也是一個對象 ) + this 指向總是善變的

this 的三篇文章按照順序復習
this基本概念 -> this綁定規則 -> this 應用實例

基本概念

this 總是返回一個對象 即包含當前屬性或者方法函數的對象, 因為對象的屬性和方法函數可以賦予另一個對象,所有 this 指向的對象也是善變的。

  function foo () {
  console.log('name :' + this.name);
  }

  var obj = { name: "obj1", foo: foo };
  var obj2 = { name: "obj2", foo: foo };
  var obj3 = { name: "obj3" };

  obj.foo()   // obj1
  obj2.foo()    // obj2
  1. 為什么 使用this
  • this 提供了一種優雅的方式來 傳遞 一個對象的引用, 使用 this 能夠得到更加 簡介的 api.

    顯式的傳遞對象的引用(eg: 函數參數傳遞) 使得代碼變得混亂和難以維護(eg: 傳遞參數的個數就是個問題)。

  • 使用 this 可以 自動引用合適的上下文環境,并且確定this當前指代的對象進而使用其屬性和方法函數

  • ** 我們使用 this 的最終目的是保證能夠正確 + 便捷的使用 對象的屬性和方法函數處理數據 **

  1. this 的使用誤解 ( this 的指向誤解 )

    1. this 并不指向函數自身

    2. this 不一定指向定義它的函數作用域或者定義時的作用域

       function foo() {
           var a = 2;
           this.bar = function() {
             console.log(this.a)
           }
         this.bar();
       }
       foo();
      
  2. this 和詞法作用域的比較

    this 可以通過 參數傳遞 或者 直接的對象引用來代替。

    ** 但是 this 因為有其更加靈活的特性才被大家所使用,總是使用詞法作用域容易讓你 回到編程的舒適區 **

我們來記錄 foo 函數被調用的次數

    function foo(num) {
        console.log('foo ' + num);

        // 記錄 foo 函數被調用的次數
        this.count++;
    }

    foo.count = 0;
    for(var i = 0; i < 5; i++) {
        foo(i);
    }

    // 記錄 foo 函數被調用的次數
    console.log(foo.count);

  分析一下上面的 輸出 的值 和 this 的指向?
  若需要你來改造 你應該怎么辦??
  1. this 的指向正解 ( 請看 this 的 四種綁定策略 )

    函數內部的this 總是指向 函數本身被調用的位置。(this 綁定規則有詳解)

    所以對于 this 的 指向就是 尋找函數的調用位置為首。(瀏覽器自帶的 開發者工具可以很方便的查看函數調用棧)

  2. this 的 三種強制綁定的 方法詳解

** javascript 提供了 call apply 和 bind 三個方法,用于固定 this 的指向 **

** call 和 apply bind 都是定義在 Function 上面的方法。**
** call apply 返回一個調用函數的執行結果。 **
** bind 返回一個修改了內部this的 包裝函數。 **

  • call 的 傳參解析 ( 4 種傳參的方式 )

    call 參數使用正常的對象

    call 參數為空、null、undefined 則默認傳入全局對象

      var n = 'bar';
      var obj = {n: 'foo'}
    
       function baz() {
         console.log(this.n)
       }
    
       baz.call(obj);        // foo
       baz.call(window);
       baz.call();
       baz.call(null),
       baz.call(undefined);
    

    call 傳入一個基本類型的數據,這個基本類型的數據會被轉為包裝對象 賦值給 this

         var f = function () {
             console.log(this);
         };
    
         f.call(5)     // Number {[[PrimitiveValue]]: 5}
    

    call 可以傳遞多個參數,第一個參數為需要綁定的對象,后面的參數 依次是函數調用的傳參參數

  • apply ( 接受一個數組作為函數執行時的參數 )

  • bind 將函數體內部的 this 強制綁定,返回一個新的經過包裝的函數

      // 自己實現的簡單功能的 bind 函數
      function bind(fun, obj) {
            return function() {    // 這個 就是 bind 返回的函數
                  fn.apply(obj);
            }
      }
    

apply call bind 使用全攻略 ( 4種使用場景 )

  1. 傳遞空對象 ** 參數柯里化 **( 看你傳遞的對象到底有多空 )

    call apply bind 傳遞一個空對象常常用于參數的柯里化

     function bar(a, b) {
           console.log(a + ',' + b);
     }
    

    直接使用 null / undefined 作為空 傳入

     var baz = bar.call(null, 1, 4)      // 1, 4
    
     var bak = bar.bind(null, 10);
     bar(19)    // 10,19
    

    傳遞進去一個 真空對象 var ? = Object.create(null);

    var baz = bar.call(?, 1, 4)       // 1, 4
    
  2. 自定義的兩種 bind 方法

    1. 創建自定義的 bind 方法函數

       function bindCopy(fn, obj) {
             return function() {
                    fn.apply(obj, arguments);            // 這里主要依賴 call 方法 ** 注意不能少了函數參數 **
              }
       }
      
    2. 擴展函數方法庫(** 重要知識點 **)

      Function.prototype.bindCopy() {
             var fn = this;
             var obj = arguments[0];
             var args = Array.prototype.slice(arguments, 1);
             return function() {
                      fn.apply(obj, args)
             }
       }
      

      重要知識點:

      • 函數使用 prototype 可以進行擴展( Function.ptototype.bindCopy )

      • 使用 apply 可以將 類數組對象( 有 length 屬性的對象 ) 進行參數結構

      • 函數自身調用時也是使用 this 表示調用的上下文

      • 注意 原函數本身的 參數不能少

  3. apply 和 call 的妙用

    1. 將數組解構 (上面是將類數組對象解構)

      var arr = [1, 4, 6, 7];
      Math.max.apply(null, arr);        // 7
      
    2. 使用 call 方法用在 對象繼承中 重新調用被子類覆蓋的父類方法;

       function Parent() {
           this.a = 'super';
           this.Super = function() {
                  console.log('父類的 Super 方法' + this. a);      
           }
       }
      
       var p = new Parent();
      
      function Children (a) {
            this.a = a;
            Parent.call(this);     // 調用 父類的構造函數
       }
      
      var c = new Children(12);
      c.Super()          // 使用子類 繼承過來的方法
      
      c.Super.call(p)        // 使用 call 重新調用父對象的方法
      

    試著自己實現一個類似 于 forEach 的 方法吧

.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,106評論 2 375

推薦閱讀更多精彩內容