箭头函数的this指向能改变吗(setTimeout中的this指向问题和箭头函数结合的区别)
导读:1、首先 首先要解释下,函数体内变量的作用域是在函数定义的时候就确定的,而不是运行时; 函数的上下文是在调用时确定的,函数体内的this指向其上下文; 箭头函数没有自己的this,它的this指向的是它上级的this,而它上级的this指向的是上级的上下文。...
1 、首先
首先要解释下 ,函数体内变量的作用域是在函数定义的时候就确定的 ,而不是运行时;
函数的上下文是在调用时确定的,函数体内的this指向其上下文;
箭头函数没有自己的this ,它的this指向的是它上级的this ,而它上级的this指向的是上级的上下文 。
2 、普通函数的this ,指向其调用者 ,箭头函数this ,指向其上级this
let app = {
a: 1,
fn: function () {
console.log(app.fn:, this, this.a);
// this指向需要函数被调用时才能确定 ,当app.fn()执行 ,
// 确定其上下文为app ,所以this指向app对象
// this.a = app.a = 1
}
}
window.a = 0
let app2 = {
a: 2,
fn: () => {
console.log(app2.fn:, this, this.a);
// app2.fn()执行 ,上下文为app2,this本应指向app2对象,
// 但是fn是箭头函数 ,所以this指向它上级的this ,也就是
// 指向app2的this,由于app2的this指向的是其上下文,所以这里就是window,
// this.a = window.a = 0
}
}
拓展:var 、let和const声明的数据 ,作用域不同 ,var声明的对象可以在global全局作用域下查找,也就是赋值给了window对象;而let和const声明的对象只能在script作用域下查找 ,所以window对象上不会显示声明的app等对象和函数 。var声明的对象和function函数都可以在global全局作用域下找到 。
说到了script ,多个script在浏览器中一般是分块编译的 ,不是同时编译 。但是作用域只有一个 ,就是script作用域 。 3 、seiTimeout中的this ,指向window ,箭头函数this ,指向其上级this let app3 = { a: 3, fn: function () { setTimeout(() => { console.log(app3.fn:, this, this.a); // app3.fn()执行 ,但输出语句在setTimeout中 , // this本应指向window,但箭头函数的this指向其上级的this , // 所以this指向fn的this ,也就是fn的上下文,this指向app3对象 // this.a = app3.a = 3 }, 1000); } } let app4 = { a: 4, fn: ()=> { setTimeout(() => { console.log(app4.fn:, this, this.a); // app4.fn()执行 ,this本应指向window , // 但箭头函数的this指向fn的this,fn的this指向app4的this, // app4的this指向app4的上下文 // 所以this指向app4的上下文 ,this指向window // this.a = window.a = 0 }, 1000); } } let app5 = { a:5, fn:function(){ setTimeout(() => { console.log(app5.fn:, this, this.a); // app5.fn()执行 ,this指向fn的this , // fn的this指向fn的上下文 ,也就是this指向app5 // this.a = app5.a = 5 }, 1000); } } 4 、数组中的函数 ,调用后的this ,指向该数组 function app6() { console.log(app6.fn:, this, this.a); } let arr = [0, 1, 2, app6] arr[3]() // 函数执行 ,上下文是arr数组 ,this指向arr , // this.a = undefined, this[0] = 0 5 、事件处理函数的this,指向触发事件的对象 6 、可用call 、apply和bind改变this指向创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!