JS之this

this是什么 ?

this 关键字是 JavaScript 中最复杂的机制之一。它是一个很特别的关键字,被自动定义在
所有函数的作用域中。但是即使是非常有经验的 JavaScript 开发者也很难说清它到底指向
什么。

this的四大绑定规则

一、默认绑定
这条规则应用于没有其他规则的默认规则。看下面的例子:

var a = 2;

function foo(){
	console.log(this.a);
}

foo();// 2

这里实际上foo函数中的this指向了全局对象,有一个细节在于,如果是严格模式下,则会指向undefined。

二、隐式绑定
当函数通过对象的属性这种方式调用时,就触发了this的隐式绑定规则,此时函数中的this会指向该对象。看下面的例子:

var a = 2;
function foo() {
	console.log(this.a);
}

let obj = {
	a: 1,
	foo: foo
}

obj.foo();	// 1

这里有一个很容易让人陷入的误区,函数是独立存在的,对象中的属性只是函数的引用,看下面的例子:

let bar = obj.foo;
bar();	//2

打印结果是2,仔细想想又显而易见,不管是bar还是obj的foo属性都是对foo这个函数的引用,bar是直接调用的,没有其他规则,所以应用了默认的绑定规则。一个更让人意想不到的结果发生在回调之中,看下面的例子:

var a = 2;
function foo() {
	console.log(this.a);
}

let obj = {
	a: 1,
	foo: foo
}

setTimeout(obj.foo, 1000);	// 2;

很多人会很惊讶为啥是2,而不是1,其实原理很简单,setTimeout的第一个参数接收一个函数,这里我们传的obj.foo是实参,在setTimeout内部接收的是形参,相当于fn = obj.foo,所以在setTimeout内部不是用obj.foo来执行,而是用fn执行的,命中默认绑定规则,所以this指向全局对象。

三、显式绑定
所谓显式绑定,也叫硬绑定,是强制将this绑定到指定的对象上。JS提供了三个函数来显式绑定this:apply、call、bind。看下面的例子:

var a = 2;

function foo() {
	console.log(this.a)
}

let obj = {
	a: 1	
}

foo.call(obj); // 1
foo.apply(obj);	// 1
foo.bind(obj)(); // 1

四、new绑定
函数中的this会自动绑定到通过new操作符创建的对象上,看下面的例子:

function Foo(a) {
	this.a = a;
}

let obj = new Foo(2);

obj.a;  // 2;

五、优先级
默认绑定是在无法应用其他绑定时应用的,所以默认绑定的优先级最低;现在我们来看一看隐式绑定和显式绑定谁的优先级高:

function foo() {
    console.log(this.a);
}

let obj1 = {
    a: 1,
    foo: foo
}

let obj2 = {
    a: 3
}

obj1.foo.call(obj2);	// 3

从打印结果来看,显式绑定的优先级高于隐式绑定,我们再来看看隐式绑定和new 操作符谁的优先级高:

function foo(a) {
    this.a = a;
}

let obj1 = {
    a: 1,
    foo: foo
}

let obj2 = new obj1.foo(3);
console.log(obj1.a); //1
console.log(obj2.a); //3

从打印结果来看,new 操作符优先级明显高于隐式绑定,最后我们再来看看显式绑定和new绑定谁的优先级更高:

function foo(a) {
    this.a = a;
}

let obj1 = {
    a: 1,
    foo: foo
}

let bar = obj1.foo.bind(obj1);
bar(3);
console.log(obj1.a);    // 3
let obj2 = new bar(5);
console.log(obj1.a);    // 3
console.log(obj2.a);    // 5

不难看出,new操作符修改了bar中的this,bar是由bind生成的函数,是硬绑定的一种,所以new 的优先级是高于显式绑定的。

得出结论: new > 显式绑定 > 隐式绑定 > 默认绑定

总结

从前面的例子中可以看出,this有四种应用规则,且this究竟应用哪一种规则不是由函数声明的时候决定,而是由调用的时候决定,在分析this的时候我们一定要小心、谨慎。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值