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上卷

    原文作者:山外de楼
    原文地址: https://segmentfault.com/a/1190000009069167
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞