this
this指向
在JavaScript中this可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式,this 绑定的对象即函数执行的上下文环境(context)。
记住规则:在ES5中,this 永远指向最后调用它的那个对象,判断this引用什么的唯一方法就是看使用this关键字的这个方法在哪里被调用的。
箭头函数的 this 始终指向函数定义时的 this,而非执行时。
我们通过以下例子来证明这一点:
var name = "window";
function a() {
var name = "ben";
console.log(this.name); // window
console.log("inner:" + this); // inner: window
}
a();
原因是a的调用对象是window,相当于 window.a(), 所以this指向了window, this.name取的是全局变量的name。
而如果像下面这样调用,输出的就是局部变量的name。
var name = "window";
var a = {
name: "ben",
fn : function () {
console.log(this.name); // ben
}
}
a.fn();
原因是fn函数的调用者是a, this指向的是a, this.name取的就是a.name。
再对上例做一下改变:
var name = "window";
var a = {
fn : function () {
console.log(this.name); // undefined
}
}
window.a.fn();
此时fn的最后调用者仍然是a,所以this指向a,而a没有局部变量name,所以输出undefined。
最后再做一下改变,我们发现输出又不同了。
var name = "window";
var a = {
name: "ben",
fn : function () {
console.log(this.name); // window
}
}
var f = a.fn;
f();
原因是a.fn赋值给f变量,但并没有执行调用。而f()执行时调用者仍然是window,所以this最终指向了window。
改变this的指向的方法:
- 使用 ES6 的箭头函数
- 在函数内部使用 _this = this
- 使用 apply、call、bind
- new 实例化一个对象
call
- 语法:func.call(thisArg, arg1, arg2, ...)
- 定义:call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
示例:
var a ={
name : "ben",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.call(a,1,2) //3
apply
- 语法:func.apply(thisArg, [argsArray])
- 定义:apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
示例:
var a ={
name : "ben",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.apply(a,[1,2]) //3
该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
bind
- 语法:func.apply(thisArg, [argsArray])
- 定义:bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
示例:
var a ={
name : "ben",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.bind(a,1,2)() //3
所以我们可以看出,bind 是创建一个新的函数,我们必须要手动去调用。 注意call、apply、bind的调用者都是function,包括构建函数。