javascript中的this

回顾一下,两年前刚刚进入这行的时候,也曾被 this 这个关键字折腾过,看了不少资料,基本上都提及到了 4 种规则:

默认绑定

默认绑定的 this 指向全局对象,严格模式下 this 指向 undefined。

function foo() {
    // window
    console.log(this);
}
foo();
/*-------------------------------*/
'use strict';
function foo() {
    // undefined
    console.log(this);
}
foo();

this 在浏览器下指向 window ,node 下指向 global

隐式绑定

函数在的调用位置是否有上下文对象,如果有,this 绑定到这个对象上。

const name = 'boy';
const obj = {
    name: '94yk',
    learn() {
        console.log(this.name + ' is learning JS');
    }
};
obj.learn();
// 94yk is learning JS

/* -------------------------- this'丢失' -------------------------- */
let learn = obj.learn;
learn();
// boy is learning JS

显式绑定

其实我更愿意称其为强制绑定哈哈哈。三个流氓 apply、call、bind 强行霸占 this 美女!

这三个函数都会劫持 this,绑定到指定的对象上。
不同的地方是:call 和 apply 会立即执行,而 bind 不会立即执行,返回 this 修改后的函数

如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值 在调用时会被忽略,实际应用的是默认绑定规则,也就是全局对象。

new 绑定

将 this 绑定到构造函数创建的实例上。

function myNew(fn, ...args) {
    let obj = Object.create(fn.prototype);    // 创建空对象,把它的__proto_指向构造函数的ProtoType
    let res = fn.apply(obj, args);            // 改变函数this指向为新建对象然后执行构造函数
    return res instanceof Object ? res : obj; // 如果执行结果是对象就返回它,没有就返回新建的对象
}

箭头函数

首先明确一点,箭头函数中没有 this!没有 this!没有 this!
你所见到的箭头函数中的 this,其实是它所在上下文外层第一个不是箭头函数的函数 this 的指向
可以看出与普通函数的显著区别: 1 不能实例化; 2this 绑定是在声明时就确定了的。
箭头函数还有一个特点就是一旦确定了 this 不会被任何代码所改变,就算是 call 也不行!

function foo() {
    return () => {
        console.log(this.a);
    };
}
foo.a = 10;
let student = {
    a: 100
};
let bar = foo.call(foo);
bar(); // 10

let baz = foo.call(student);
baz(); // 10  惊不惊喜,意不意外!因为在上一次call时,this已经确定了它的对象是谁!不能三心二意呀!

总结

要知道 this 存在的原因就是为了方便程序员的书写,相比 window.xxx/someObj.xxx,this.xxx 显然来的更加简单便捷,可以看做它只不过是你调用的方法所在上下文的一个代理而已。简单一句话:谁调用的这个方法,this就指向谁

现在可以分析下隐式绑定里 this "丢失"的问题:

// 这一步其实就是创建了个learn并将其指向obj对象下的learn方法,这个时候并不知道会是谁去调用这个方法。
let learn = obj.learn;
// learn() ==> 其实就是 window.learn(),自然里面的this代理的就是window, window下的name为boy
learn();

解决办法也很简单,根据箭头函数的特点可以轻易应对:

const name = 'boy';
const obj = {
    name: '94yk',
    learn() {
        () => {
            console.log(this.name + ' is learning JS');
        };
    }
};
let learn = obj.learn();
learn();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yokiizx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值