以下兩題都只考慮瀏覽器環境
第一題:讀代碼,並寫出打印結果
var length = 10
function fn() {
console.log(this.length)
}
var obj = {
length: 5,
method: function (fn) {
fn()
arguments[0]()
}
}
obj.method(fn, 1, 2, 3, 4, 5)
答案解析:
代碼開始執行,調用了對象obj的method方法,並傳入了六個參數:fn, 1, 2, 3, 4, 5,其中fn就是已經定義了的fn函數,method方法本質也是一個函數,在執行的時候接收到了六個形參(fn, 1, 2, 3, 4, 5),但是其自身只定義了一個實參,也就是隻接收了fn並在其內部代碼的第一行執行了fn,函數內部的this是誰調用,this就指向誰,此時fn的調用者是默認的window,所以this.length的打印值爲10。
接下來開始解析代碼arguments[0]()
,arguments爲method方法接收到的形參類數組,其第一項是fn,此時fn的調用者是arguments對象,所以fn內部的this指向了argument對象,arguments作爲一個類數組,其內部有length屬性標識了形參的個數,所以輸出的打印值爲6。
拓展:
函數執行時形參和實參的個數不一致時,如果實參多於形參,則按照從前往後的順序,後面多出的實參爲undefined
function arg(f1,f2,f3){
console.log(f1) //1
console.log(f2) //undefined
console.log(f3) //undefined
}
arg(1)
如果形參多於實參,則多出來的形參可以通過arguments對象獲取到
function arg(f1){
console.log(f1) //1
console.log(arguments) //Arguments(3)
}
arg(1,2,3)
第二題:讀代碼,並寫出打印結果
function a(xx) {
this.x = xx
return this
}
var x = a(5)
var y = a(6)
console.log(x.x)
console.log(y.x)
答案解析:
函數a的返回值是this,所以當代碼運行完var x = a(5)時,此時x爲window,var y = a(6)執行之後,此時y爲window,x被重新賦值成了6,接下來第一個console語句,打印的是6.x,6是一個數字,所以第一個console輸出爲undefined。
第二console語句,輸出的是window下面的x,所以輸出值爲6。
拓展:
如果代碼是下面這樣,此時打印值是什麼
function a(xx) {
this.x = xx
return this
}
var x = a(5)
console.log(x.x)
答案解析:
此時的打印出的是瀏覽器的頂級對象window,當var x = a(5)運行的時候,首先函數a中的代碼this.x = xx將x賦值爲5,但是隨即被var x =a(5)給重新賦值成了window。
無論是打印x.x還是x.x.x.x.x(點出任意多個x),輸出結果都是window對象。