一個小小的JavaScript題目

 今天前Leader在下班前發給我一道JavaScript的題目,看到感受很不錯,並且我開始的時候確實也理解錯了,以爲有必要拿出來說講,而且爲此我也作錯了地鐵,哈哈哈~
  題目是這樣的:javascript

var length = 10;
function fn() {
    console.log(this.length)
};
var obj = {
    length: 5, 
    method: function (fn) {
        fn();
        arguments[0]();
        fn.call(obj, 12);
    }
};
obj.method(fn, 1);

  請問輸出是什麼,當時那手機看的時候給出了答案java

10 10 5

  實際上並非如此,答案是:git

10 2 5

  仔細分析了一下才知道緣由,首先介紹一下四種this的類型:github

  1. 默認綁定數組

  2. 隱式綁定app

  3. 顯示綁定函數

  4. new綁定this

其中,默認綁定就是什麼都匹配不到的狀況下,非嚴格模式this綁定到全局對象window或者global,嚴格模式綁定到undefined;隱式綁定就是函數做爲對象的屬性,經過對象屬性的方式調用,這個時候this綁定到對象;顯示綁定就是經過applycall調用的方式;new綁定就是經過new操做符時將this綁定到當前新建立的對象中,它們的匹配有限是是從小到大的。
  那麼如今來解釋一下:code

obj.method(fn, 1);

  上述執行其實對應的是下面三條語句:對象

fn(); 
arguments[0]();
fn.call(obj, 12);

  經過將函數賦值給函數參數(fn),而後調用fn,這個時候能匹配到的this類型就是第一條默認綁定,由於實在非嚴格模式下,因此this綁定的是window,固然首先輸出的是10
  先解釋一下第三個,這個也很簡單,由於用了call,因此實際匹配了顯示綁定,因此當前this綁定了obj,那麼輸出的確定是2
  下面着重解釋一下第二個,這個我當時理解成和第一次徹底同樣,但實際並非的,其實在JavaScript中數組算是一種特殊的對象(關於JavaScript對象的部分,我如今還在寫,下一篇就會出的),arguments[0]其實就是經過對象的屬性去調用(數組的默認屬性類型是數值而普通對象的屬性類型是字符串),那麼如今其實運用的是規則2,this被綁定到arguments上,而arguments確實存在一個length屬性,而且值爲2(這個別告訴我你看不出來),因此輸出的確定就是2啦。
  可見《你不知道的JavaScript》這本書說的很對,之因此會在ES6出現箭頭函數,實質就像用詞法做用域代替this,由於這個真的特別特別容易誤用和讓人誤解。
  歡迎你們到個人我的博客看看,https://mrerhu.github.io ?

相關文章
相關標籤/搜索