前言
JS中的重中之重,也是在面试中被问得最多的问题,在这里this到底是什么?我也时常疑惑于此,特用此文来整理思路理解并方便日后回顾。
函数的调用
JS(ES5)里面有三种函数调用形式:
func(p1, p2) //等价于func.call(undefined, p1, p2)
obj.child.method(p1, p2) //等价于obj.child.method.call(obj.child, p1, p2)
func.call(context, p1, p2)
把所有的调用转换成call的形式后,this指的就是call后面的第一个参数。
特别注意,全局定义的函数转换成call的形式后,虽然第一个参数为undefined,但是由于全局定义的函数都是挂载到window/global对象上的,所以this会指向window/global。
this是什么?
看调用并转换
- 例子1
function showName(){
console.log(this); //this是window
}
showName();//showName.call(undefined)
看调用,showName是全局定义函数,挂载在window对象上,所以this是window。
- 例子2
var name="hello window!";
function testName () {
var name="hello this!";
console.log(this.name);
}
testName();//testName.call(undefined)
为什么log出来的不是"hello this!"而是"hello window!"呢?
同样,testName也是挂载在window上的,所以testName函数在调用时this是window,
所以打出来的自然是window.name,也就是全局变量name的值"hello window!"而不是"hello this!"。
- 例子3
var obj={
a:"哈哈哈",
b:function(){
var a="嘿嘿嘿";
console.log(this.a);//"哈哈哈"
}
};
obj.b();//obj.b.call(obj)
那么以上代码为什么会打出"哈哈哈"呢?
显然,这里的this是指obj,也就是会去找obj.a,所以打出的就是"哈哈哈"啦。
总结
fn() this=>window/global
obj.fn() this=>obj
fn.call(xxx) this=>xxx
fn.apply(xxx) this=>xxx
fn.bind(xxx) this=>xxx
new Fn() this=>新的对象
fn = () =>{} this=>外面的this
方法:
1.看源码中对应的函数是怎么被 call 的(这是最靠谱的办法)
2.看文档
3.console.log(this)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。