this
- 在面試中,js指向也常常被問到,在開發過程中也是一個需要注意的問題,嚴格模式下的this指向undefined,這里就不討論。
普通函數
- 記住一句話哪個對象調用函數,該函數的this就指向該對象。總指向它的調用者。
obj.getName() 無疑會打印出'黃傑',b()可以寫成window.b(),調用的對象為window,因此訪問的name為全局的變量。
var name = '車神'
var obj = {
name: '黃傑',
getName: function(){
console.log(this.name)
}
}
var b = obj.getName
obj.getName()// '黃傑'
b() // '車神'
- 但是下面的代碼,可能就會有點疑惑了,為什么打印的是undefined,因為全局使用var聲明的變量會成為window的屬性,而ES6的let、const聲明的變量不再是window的屬性,通過window.name不能訪問該屬性。
let name = '車神'
let obj = {
name: '黃傑',
getName: function(){
console.log(this.name)
}
}
let b = obj.getName
b() // undefined
箭頭函數
- 箭頭函數在定義時就決定了this的指向,定義時所處的上下文環境對象即為this的指向,全局的上下文環境對象為window。
有些人認為不應該是兩個都是'黃傑嗎'?js中的執行上下文有全局、函數、Eval執行上下文,對象並不是執行上下文,因此它會一直往上尋找最近的執行上下文。即為window。
var name = '車神'
var obj = {
name: '黃傑',
getName: () =>{
console.log(this.name)
}
}
var b = obj.getName
obj.getName()// '車神'
b() // '車神'
new操作符
- 從這篇文章看到js的new操作符深度解析,new操作符做了以下幾件事。this指向了其過程中創建的空對象。
1、創建一個空的簡單JavaScript對象(即{});
2、鏈接該對象(即設置該對象的構造函數)到另一個對象 ;
3、將步驟1新創建的對象作為this的上下文 ;
4、如果該函數沒有返回對象,則返回this。
面試題一
- 這是我目前看到最有意思的面試題,先思考兩分鍾...
var length = 100
function foo(){
console.log(this.length)
}
var obj = {
length: 10,
getLength(cb){
cb()// 打印啥?
arguments[0]()// 打印啥?
}
}
obj.getLength(foo, length, obj)
1.答案是100、3。
2.cb()調用的對象為window,arguments[0] ()的調用對象為arguments,它是一個偽數組,也是一個對象,length為函數調用時傳遞參數的長度,因此打印3。
面試題二
- 這道題也有點意思,還做錯了,先思考兩分鍾
function foo(xx){
this.x = xx
return this
}
var x = foo(5)
var y = foo(6)
console.log(x.x)// 打印啥?
console.log(y.x)// 打印啥?
1.答案是undefined、6,兩次調用this都指向window。
2.當執行foo(5)時,得到window.x = window,window.x.x = 5。
3.當執行foo(6)時,this.x = 6相當於window.x = 6,不再是window.x = window,此時window.x並沒有x屬性,因此通過x.x訪問不存在的屬性為undefined。