说到this,入前端坑的人都知道这是JS初期语言毕竟之路。不少人(我就是)对于this的了解很模糊,或者不够全面。最近打算在反过来在看下es6,在es6中又出现了箭头函数对于this的理解有多了层认识。因此就在写一遍来增强本身的认知。前端
在讲this以前,咱们先把做用域链在复习一下es6
在红宝书中对做用域链的描述有这么一句话:当代码在一个环境中执行时,会建立变量对象的一个做用域链。做用域链的用途是保证对执行环境有权访问的全部变量和函数的有序访问
简单来讲,做用域链的做用就是在函数使用一个变量的时候,由近到远的查找有自身内部想最顶层也就是window的做用域中查找。app
咱们做用域链明白了,咱们讲一下this.函数
this又分传统this和箭头函数中的thisthis
传统this的指向:spa
1.this老是指向它的直接调用者。code
2.在非严格模式下当没有调用者的时候,默认指向最顶层也就是window对象
3.在严格模式下('use strict')当没有调用者的时候,this就是undefinedblog
4.在call、apply、bind绑定的时候,默认指向绑定的对象继承
箭头函数中this的指向:
1.箭头函数自身不包含this,它是继承与他所处的宿主对象的this。
光写概念,不说看得烦,我敲得也烦。直接上代码吧。
实例一:this指向它的直接调用者
var myObj = {
myVal : 3,
myFnc : function(){
console.log(this);
}
}
myObj.myFnc();//myobj
此时myObj调用了因此this指向于myObj;
实例二:非严格模式下没有调用者的时候
function myFnc(){
console.log(this);
}
myFnc();//window
此时,由于没有调用者,因此this默认指向最顶层也就是window
实例三:严格模式下没有调用者的时候
function myFnc(){
'use strict'
console.log(this);
}
myFnc() //undefined
此时,没有调用者,又由于当前是严格模式因此打印出来的this是undefined
实例四:call、apply、bind绑定的时候function myFnc1(){
function myFuc1(){
console.log(this);
}
function myFnc2(a,b){
console.log(this);
}
myFnc2.call(myFnc1);//myFnc1
此时绑定的就是myFnc1,因此当前this的指向就是myFnc1;
call和apply的绑定机制大体是同样的,因此就不一一解释了。
var myObj = {
myFnc :function(){
setTimtout(function(){
console.log(this);
}.bind(this))
}
}
myObj.myFnc();//myObj
由于在定时器函数中,没有调用者,因此默认指向window。又由于使用bind()方法给回调函数直接绑定了当前this指向,因此当前this指向就是myObj。
是否是感受这么写很麻烦,当今的ES6的年代,还用啥bind绑定。若是须要返回当前函数伸手就是一个箭头函数
实例五:箭头函数简易版
var myObj = {
myFnc :function(){
setTimeout(() => {
console.log(this)
})
}
}
myObj.myFnc();
由于箭头函数继承的是它的宿主对象的this,也就是继承的myFnc的this,而myFnc的This指向是myObj,因此打印出来的当前this指向就是myObj;
实例六:箭头函数嵌套版
var myObj = {
myFnc :function(){
function childFnc(){
setTimeout(() => {
console.log(this)
})
}
childFnc();
}
}
myObj.myFnc();
小小的思考一下。。。
若是你一瞬间就明白的话,那就代表你已经通关了。
由里到外的分析,你就会发现很简单。
由于箭头函数,当前this继承于它的宿主也就是childFnc。childFnc方法的执行,由于没有调用者。因此它的this指向的是window。因此当前打印的this指向就是window。
总结:
this指向简单的说就是谁调用就指向谁,没调用就指向window(严格模式undefined)
当出现箭头函数内的,就指向宿主元素。