前言
你們好,來掘金有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);函數
- 能夠看到第一句中第一個參數傳了fn函數的引用,第二個參數傳了數字1
- 由於第一句調用了obj對象中的method方法,因此剛剛傳的參數也是傳到了method中,method函數接收fn函數引用且在裏面執行了fn();,咱們能夠去看fn函數裏有一個console.log輸出語句,輸出this.length,那咱們只須要搞清楚this是誰就能夠獲得輸出結果。
- 重點來了!
- 接着上面的分析咱們如今想知道this,你們可能會想了,通常狀況下this不就是誰最終調用的this就是誰嗎,那這裏是obj調用的method,那麼this確定是obj,obj裏面不是恰好有length屬性嗎,那輸出結果不就是5嗎?(很不幸的告訴你們,若是你這樣想那就掉進陷阱了)
- 實際上由於fn是做爲形參傳遞進來的,且fn函數是聲明在全局做用域的,因此即便在obj的method方法中調用,那麼他的this依舊是window,因此method方法中的fn函數執行後輸出結果是10
- 爲了你們閱讀方便我再把原題貼一遍,順便把剛剛分析過的代碼的執行結果加上
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
複製代碼
- 這裏第二句咱們看到是這樣的一行代碼:arguments[0]();
- 咱們知道arguments是個數組,裏面存放的是所在函數接收到的全部形參集合,那麼這麼存放的確定是fn函數的引用和1,它訪問了arguments[0],那麼很明顯仍是調用了fn函數,那麼又遇到了fn函數中的console.log(this.length)這條輸出語句。
- 那麼咱們繼續探索一波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和2
ui
總結
想要作對這道題只須要基本掌握this指向和arguments是什麼就能夠輕鬆應對啦this
大佬們若是發現了文中的錯誤,及時在評論區指出,我會及時修改!spa
若是以爲對您有用請點個贊,謝謝大佬!
code