深度剖析JS中this绑定

this到底是什么?

当一个函数被调用时,会创建一个活动记录(有时候也称执行上下文),这个活动记录会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息,this就是记录的其中一个属性。this是在运行时进行绑定的,并不是在编写时,它的上下文取决于函数调用时的各种条件。this的绑定和和函数声明位置没有任何关系,只取决于函数的调用方法(也就是函数调用位置)。

 this绑定规则:默认绑定、隐式绑定、显示绑定、New 绑定

默认绑定:函数直接使用不带任何修饰的函数引用进行调用this默认绑定全局对象,特别指出在ES5严格模式(strict mode)下全局对象无法使用默认绑定,因此this会绑定undefined;如:预编译过程中(函数预编译)this指向window、全局作用域:this指向window、全局方法setTimeout()、setIntervail():this指向window

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

var a = 2;

foo(); //2

 隐式绑定:obj.func():隐式绑定规则会把函数调用中的this绑定到这个上下文对象

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

var obj = {
    a:2,
    func:func
}

obj.func(); //2

隐式绑定this丢失问题:看下面代码,虽然bar是obj.func()的一个引用,但是实际上,它引用的是func函数本身,因此此时bar()其实是一个不带任何修饰的函数调用,因此应用的默认绑定。

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

var obj = {
    a:2,
    func:func
}

var bar = obj.func();

var a = "global";

bar();//global

 间接调用函数、js内置函数(setTimeout)与上述情况也类似,即使使用隐式绑定,回调中this也会丢失,这就是隐式丢失


显示绑定:call/apply/bind:可以改变this指向

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

var obj = {
    a:2
}

//call语义为:改变this并执行
func.call(obj);//2

但是这种绑定方式仍然无法解决隐式丢失问题 

硬绑定(显示的强制绑定):显示绑定的一个变种

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

var obj = {
    a:2
}

var bar = function (){
    foo.call( obj );
}

bar();//2

setTimeout(bar,100);//2

绑定过程:异步也好间接调用也罢都是回调问题,之前我们在外面隐式调用会造成隐式丢失的问题,现在我们直接在回调函数内部显示绑定通过call来强制的改变this,所以无论外面如何调用函数bar,总会手动的在obj上调用foo,即this绑定到了obj上。

硬绑定原理:其实就是通过创建一个包裹函数,内部手动绑定想要调用函数的this,并返回这个函数。(相当于在调用函数时搭了一道桥,这个桥的作用就是绑定this)

 API调用的上下文:以数组的forEach为例,都知道forEach方法有两个参数第一个为函数,第二个就是this绑定的上下文(context),其内部就是通过call、apply实现了显示绑定。


 new 绑定

在了解new绑定之前我希望大家能够明白一点:在javascript中,构造函数只是一些使用new操作符时被调用的普通函数。

在使用new调用函数,或者说发生构造函数调用调用时,会自动执行以下操作:

  1. 创建一个全新的对象(这个全新的对象就是this)
  2. 这个新对象会被执行【原型】连接
  3. 这个新对象会绑定到函数调用的this
  4. 如果这个函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象

 四种绑定方式优先级

1.默认绑定:优先级最低

2.隐式绑定:第三高

3.显示绑定:第二高

4.new绑定:第一高

 

 

拓展ES6箭头函数this指向问题:

预热:箭头函数没有this、arguments、super(ES6);箭头函数不能使用new操作符,不能当做构造函数来用、没有prototype;可以表示数据流方向,方便javascript引擎优化;

箭头函数this绑定原理:绑定最近非箭头函数作用域中的this

 

今天就介绍到这里,有用就顺手点个赞,谢谢!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值