一 this总览。
首先我们知道this的指向是在调用函数的时候确定的,(执行上下文知识)。因此,一个函数中的this指向,可以非常灵活。同一个函数调用方式不同,this指向就不同,this的指向可不是静态的哦。 而且在函数内部不能修改this。
如果调用者函数被某一个对象所拥有,那么this指向这个对象,如果调用者函数单独调用那么,this指向undefined。非严格模式this指向全局window。
从结论中我们可以看出,想要准确确定this指向,找到函数的调用者以及区分他是否是独立调用十分关键。
有很多例子:
function foo() {
console.log(this.a)
}
function active(fn) {
fn(); // 真实调用者,为独立调用
}
var a = 20;
var obj = {
a: 10,
getA: foo
}
active(obj.getA);
这个情况输出的是20,全局变量,active()执行的时候this指向全局对象window。
二:改变this指向:call,aplly,bind
一个例子
function Person(name, age) {
// 这里的this指向了谁?
this.name = name;
this.age = age;
}
Person.prototype.getName = function() {
// 这里的this又指向了谁?
return this.name;
}
// 上面的2个this,是同一个吗,他们是否指向了原型对象?
var p1 = new Person('Nick', 20);
p1.getName();
var p1 = new Person('Nick', 20);
首先我们知道,new的过程:新建对象,添加原型,改变this指向,返回对象。所以,这个Person函数的this指向新对象,随后新对象返回给了p1,我们可以说,这个this指向p1.
p1.getName();
执行getName(),这个方法被p1拥有,所以this指向p1
三 这样的问题
很多反直觉的事情发生:
var myObj = {
name : "极客时间",
showThis: function(){
console.log(this)
function bar(){console.log(this)}
bar()
}
}
myObj.showThis()
你会以为bar的this和第一个this一样,其实不一样。函数bar中的this指向的是全局window对象,而函数showThis中的this指向的是myObj对象因为这个bar()是单独调用的,没有被某一个对象拥有。 所以你可以用一个self保存this。 也可以用箭头函数,箭头函数不会创建函数上下文,所以this就是继承调用函数的this。
四、总结
首先,在使用this时,为了避坑,你要谨记以下三点:
- 当函数作为对象的方法调用时,函数中的this就是该对象;
- 当函数被正常调用时,在严格模式下,this值是undefined,非严格模式下this指向的是全局对象window;
- 嵌套函数中的this不会继承外层函数的this值。 最后,我们还提了一下箭头函数,因为箭头函数没有自己的执行上下文,所以箭头函数的this就是它外层函数的this