開開森森學前端

前言

你們好,來掘金有3個多月了,決定跟隨前端大佬們的步伐,故決定記錄本身的成長軌跡,因爲水平有限,對於文章中出現的理解等有問題還請大佬們指正。javascript

先來瞄一眼題目

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

能夠看到本題考查的知識點考察瞭如下知識點前端

  • this指向(不過好在算是this裏最簡單的)
  • 做用域
  • arguments僞數組(僞數組就是裏面操做數組的各類方法都沒有,但它有length屬性
  • 其實這裏還考察了函數的參數是按值傳遞的這個概念。

1.在向參數傳遞基本類型的值時,被傳遞的值會被複制給一個局部變量(即命名參數,或者用 ECMAScript 的概念來講,就是 arguments 對象中的一個元素)。java

2.在向參數傳遞引用類型的值時,會把 這個值在內存中的地址複製給一個局部變量,所以這個局部變量的變化會反映在函數的外部。數組

題目分析與解析

程序第一句:執行了obj.method(fn,1);函數

  1. 能夠看到第一句中第一個參數傳了fn函數的引用,第二個參數傳了數字1
  2. 由於第一句調用了obj對象中的method方法,因此剛剛傳的參數也是傳到了method中,method函數接收fn函數引用且在裏面執行了fn();,咱們能夠去看fn函數裏有一個console.log輸出語句,輸出this.length,那咱們只須要搞清楚this是誰就能夠獲得輸出結果。
  3. 重點來了!
  4. 接着上面的分析咱們如今想知道this,你們可能會想了,通常狀況下this不就是誰最終調用的this就是誰嗎,那這裏是obj調用的method,那麼this確定是obj,obj裏面不是恰好有length屬性嗎,那輸出結果不就是5嗎?(很不幸的告訴你們,若是你這樣想那就掉進陷阱了)
  5. 實際上由於fn是做爲形參傳遞進來的,且fn函數是聲明在全局做用域的,因此即便在obj的method方法中調用,那麼他的this依舊是window,因此method方法中的fn函數執行後輸出結果是10
  6. 爲了你們閱讀方便我再把原題貼一遍,順便把剛剛分析過的代碼的執行結果加上
var length = 10;
function fn() {
   console.log(this.length);
}
var obj = {
 length: 5,
 method: function(fn) {
   fn();//10
   arguments[0]();
 }
};
obj.method(fn, 1);
複製代碼
  1. 這裏第二句咱們看到是這樣的一行代碼:arguments[0]();
  2. 咱們知道arguments是個數組,裏面存放的是所在函數接收到的全部形參集合,那麼這麼存放的確定是fn函數的引用和1,它訪問了arguments[0],那麼很明顯仍是調用了fn函數,那麼又遇到了fn函數中的console.log(this.length)這條輸出語句。
  3. 那麼咱們繼續探索一波this指向,在這裏咱們須要知道做爲arguments成員之一調用的時候,其做用域就綁定到了arguments上,換句話說也就是this指向了arguments數組對象,剛剛說過arguments是有length屬性的,由於method方法的形參總共傳了2個(fn和1),那麼arguments的length就是2,既然fn裏的this指向arguments對象,因此this.length就等因而arguments.length,因此最後輸出2。 而不是10或5

最終獲得的答案

依次輸出10和2ui

總結

想要作對這道題只須要基本掌握this指向和arguments是什麼就能夠輕鬆應對啦this

大佬們若是發現了文中的錯誤,及時在評論區指出,我會及時修改!spa

若是以爲對您有用請點個贊,謝謝大佬!code

相關文章
相關標籤/搜索