js中的this总结

发布时间:2019-08-14 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了js中的this总结脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

关于this的指向问题算的上是js中的一个十分重要的问题了。今天把这个问题总结下,加深下自己对this的理解。
首先,this的指向问题可以用一句话总结就是:this总是指向调用的对象,也就是说this指向谁与函数声明的位置没有关系,只与调用的位置有关。这是判断this的一个大体原则,而具体的小原则按照优先级的不同大致可以分为以下几点:

一.优先级:new绑定>显式绑定>隐式绑定>默认绑定

1.new绑定

new方式是优先级最高的一种调用方式,也就是说只要是出现new方式来调用一个函数,this肯定会指向new调用函数新创建的对象。

function() thisTo(a){
 this.a=a;
}
VAR data=new thisTo(2); //在这里进行了new绑定
console.LOG(data.a);  //2

2.显式绑定

显示绑定指的是通过call()和apply()方法对函数进行的调用,对this影响的优先级仅次于new绑定。

function thisTo(){
   console.log(this.a);
}
var data={
    a:2
}; 
thisTo.call(data));  //2

3.隐式绑定

隐式绑定是指通过对象的属性进行添加,从而调用this所在函数,该方式的优先级在显示绑定之后。

function thisTo(){
   console.log(this.a);
}
var data={
    a:2,
    foo:thisTo //通过属性引用this所在函数 
};
data.foo(); //2

4.默认绑定

默认绑定是指当上面这三条绑定规则都不符合时采用的绑定规则,默认绑定会把this默认绑定到全局对象中,是优先级最低的绑定规则。

function thisTo(){
   console.log(this.a);
}
var a=2; //a是全局对象的一个同名属性
thisTo(); //2

二.this绑定的特殊情况

1.隐式丢失

当进行隐式绑定时,如果进行一次引用赋值或者传参操作,会造成this的丢失,从而最后将this绑定到全局对象中去。

1.1 引用赋值丢失

function thisTo(){
   console.log(this.a);
}
var data={
    a:2,
    foo:thisTo //通过属性引用this所在函数 
};
var a=3;//全局属性

var newData=data.foo; //这里进行了一次引用赋值 
newData(); // 3

原理:因为newData实际上引用的是foo函数本身,跟data对象没有任何关系,data对象只是一个中间桥梁。而newData就是一个本身不带a属性的对象,自然最后只能把a绑定到全局对象上了。

1.2传参丢失

function thisTo(){
   console.log(this.a);
}
var data={
    a:2,
    foo:thisTo //通过属性引用this所在函数 
};
var a=3;//全局属性

setTimeout(data.foo,100);// 3

原理:setTimeout(fn,delay) { fn(); } 实际上fn是一个参数传递的引用(fn=data.foo),与引用丢失的原理一样

1.3 Function.prototype.bind()
了解决隐式丢失的问题,ES5提供了bind方法,bind()会返回一个硬编码的新函数,它会把参数设置为this的上下文并调用原始函数。

function thisTo(){
   console.log(this.a);
}
var data={
    a:2
}; 
var a=3;
var bar=thisTo.bind(data);
console.log(bar()); //2

2.间接引用

间接引用是指一个定义对象的方法引用另一个对象存在的方法,这种情况下会使得this进行默认绑定。

function thisTo(){
   console.log(this.a);
}
var data={
  a:2,
  foo:thisTo
};
var newData={
  a:3
}
var a=4;
data.foo(); //2
(newData.foo=data.foo)() //4

原理:newData.foo=data.foo的返回值是目标函数的引用,因此调用的位置实际上是foo(),根据之前的隐式丢失里面说的原则,这里会应用默认绑定。

3.ES6箭头函数

ES6的箭头函数在this这块是一个特殊的改进,箭头函数使用了词法作用域取代了传统的this机制,所以箭头函数无法使用上面所说的这些this优先级的原则,注意的是在箭头函数中,是根据外层父亲作用域来决定this的指向问题。

function thisTo(){
   setTimeout(function(){
    console.log(this.a);
},100);
}
var obj={
 a:2
}
var a=3;
thisTo.call(obj); //3

不用箭头函数,发生隐式丢失,最后的this默认绑定到全局作用域,输出3。

function thisTo(){
   setTimeout(()=>{
    console.log(this.a);
},100);
}
var obj={
 a:2
}
var a=3;加粗文字
thisTo.call(obj); //2

用了箭头函数,不会发生隐式丢失,this绑定到外层父作用域thisTO(),thisTo的被调用者是obj对象,所以最后的this到obj对象中,输出2。

如果不用箭头函数实现相同的输出,可以采用下面这种方式:

function thisTo(){
   var self=this; //在当前作用域中捕获this 
   setTimeout(function(){
    console.log(self.a); //传入self代替之前的this
},100);
}
var obj={
 a:2
}
var a=3;
thisTo.call(obj); //2

三.总结:

this的绑定机制,就是要找到这个函数的直接调用位置,然后应用绑定的四条规则,当出现满足多个规则时,按照优先级的高低决定最终的绑定规则。此外注意几种特殊情况,特别是ES6中的箭头函数。

四.参考书籍

你不知道的JavaScript上卷

脚本宝典总结

以上是脚本宝典为你收集整理的js中的this总结全部内容,希望文章能够帮你解决js中的this总结所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。