JavaScript中的this(保证学会)

325 阅读3分钟

虽然this在JavaScript中是一个老生常谈的问题,但实际场景中还是很容易出错。主要原因是this对象在JavaScript中和其他语言相比表现不太一致,而且在不同的运行环境中表现也不一致。 今天我们就把浏览器中的this对象彻底聊明白,记清楚。

本文我们只讨论JavaScript在浏览器、非严格模式下this表现,在其他执行环境(比如Node.js)this的表现又不太一样了。

我们分几种情况来看:

普通的函数调用

function f(){
    console.log(this === window// 打印:true
}
f();

普通的函数调用this就是window对象,我们可以这样理解f()就等价于window.f()

我们修改一下上面的例子

function f(){
    console.log(this === window// 打印:true
}

function f1(){
    f()
}
f1()

此时仍然打印true,因为虽然f方法在f1方法中调用,但是调用f()方法的前面仍然是省略的Window对象,所以this还是Window。

函数赋予某个自变量

function f(){
    console.log(this// 打印:{fun: ƒ}
}
obj={
    fun: f
}
obj.fun();

此时this输出的是obj对象,即调用f方法的对象。

通过以上两种情况你可能感觉自己已经完全理解this了。那我们把上面的例子稍微改造一下。

function f(){
    console.log(this// 打印:Window对象
}
obj={
    fun: f
}
let objf = obj.fun; // 修改了这一行
objf(); // 修改了这一行

此时this打印出来又成了Window对象,是不是让你大跌眼睛。我们可以这样去理解,objf()就等价于window.objf(),调用上下文自然就变成了Window,和前两个例子的表现并不冲突。this要看最终调用方法的对象。

原型链中的this

let obj = {
    f : function(){
        console.log(this)  
    }
}
let obj1 = Object.create(obj);
obj1.s = 100;
obj1.f(); // 打印obj1对象

原型链中,this是调用方法的对象,和前面几个例子的表现一致。

多层级调用时的this

let obj = {
    s200,
    f : function(){
        console.log(this)  
    }
}
let obj1 = {
    obj: obj,
    s100
}
obj1.obj.f() // 打印obj对象

通过打印结果可以看出,this是obj对象。「存在多层调用时,this是最靠近f()方法的对象」

使用new实例化对象

function f(){
    console.log(this// 打印:f方法对象
}

let obj=new f();

使用new实例化对象时,this代表被实例化的对象。

bind、apply和call方法

function f(){
    console.log(this// 打印:f方法对象
}
f(); // 打印Window对象
let obj={a:10};
let r = f.bind(obj); 
f(); // 打印Window对象
r(); // 打印obj对象
f.apply(obj,[]); // 打印obj对象

bind方法会返回一个和f方法有相同函数体和作用域的函数,同时this对象永久的绑定在obj对象上。不管任何调用方式,this都是obj对象。 但是这并不会对f方法本身产生影响,所以f()方法直接调用时,还是返回了Window对象。

apply方法也有改变执行上下文的作用,apply的第一个参数就是函数的执行上下文,所以打印了obj对象。call方法和apply雷同就不赘述了。

箭头函数

箭头函数的作用非常简单,就是让箭头函数内的this对象和箭头函数外面的上下文保持一致。

总结

上面场景看起来很多,其实总结起来很简单。「不显式指定调用对象时,相当于调用省略了window,this都是window对象,;当显式指定调用对象时,this是最靠近调用函数的对象」。当然对于bindapplycall方法单独记忆就好了,因为这三个函数本身就是 为了改变this指向。箭头函数就是为了不改变this指向。

诚邀关注公众号:一行舟
我会每周更新技术文章,和大家一起学习进步。