JavaScript 基础系列之 this 指向问题
yuanyuanbyte opened this issue · 0 comments
yuanyuanbyte commented
本系列的主题是 JavaScript 基础,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
this 指向问题
- 在函数体中,函数内的
this
会被绑定到全局对象window/global
上(非严格模式下)。严格模式下,函数内的this
会被绑定到undefined
上。 - 使用
new
方法调用构造函数时,构造函数内的this
会被绑定到新创建的对象上。 - 通过
call/apply/bind
方法显式调用函数时,函数体内的this
会被绑定到指定参数的对象上。 - 通过上下文对象调用函数时,函数体内的
this
会被绑定到该对象上。 - 在箭头函数中,箭头函数没有自己的
this
,箭头函数的this就是上下文中定义的this。 - 在定时器中,
this
指向window
,因为定时器中采用回调函数作为处理函数,而回调函数的指向window
全局环境中的 this
- 在函数体中,非显式或隐式地简单调用函数时,在严格模式 下,函数内的this会被绑定到undefined上,在非严格模式下则会被绑定到全局对象window/global上。
例子1:
function f1() {
console.log(this);
}
function f2() {
"use strict";
console.log(this);
}
f1(); // window
f2(); // undefined
例子2:
var foo = {
bar: 10,
fn: function () {
console.log(this)
console.log(this.bar)
}
}
var fn1 = foo.fn
fn1()
// window
// undefined
上下文对象调用中的 this
- this 指向最后调用它的对象。
例子1:
var foo = {
bar: 10,
fn: function() {
console.log(this)
console.log(this.bar)
}
}
foo.fn()
// {bar: 10, fn: ƒ}
// 10
例子2:
var person = {
name: 'Lucas',
brother: {
name: 'Mike',
fn: function() {
return this.name
}
}
}
person.brother.fn() // Mike
// 最后的this指向的是 brother
定时器中的 this
定时器 setTimeout()
中函数里的this
默认是window
:
const obj = {
index: 1,
a: function () {
console.log(this.index)
window.setTimeout(function name() {
console.log('定时器 this.index', this.index);
console.log('定时器 this', this);
}, 1000)
}
}
obj.a()
// 执行情况:
1
定时器 this.index undefined
定时器 this Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, …}
我们也可以通过箭头函数使定时器里的this
和外层的this
保持一致:
const obj = {
index: 1,
a: function () {
console.log(this.index)
window.setTimeout(() => {
console.log('定时器 this.index', this.index);
console.log('定时器 this', this);
}, 1000)
}
}
obj.a()
// 执行情况:
1
定时器 this.index 1
定时器 this {index: 1, a: ƒ}
箭头函数中的 this
在箭头函数中this的一个常见情况:对象字面量里的箭头函数
var name = 'window';
var A = {
name: 'A',
sayHello: () => {
console.log(this.name)
}
}
A.sayHello();// 以为输出A ? 错啦,其实输出的是window
我相信在这里,大部分同学都会出错,以为sayHello是绑定在A上的,但其实它绑定在window上的,那到底是为什么呢?
一开始,我重点标注了“该函数所在的作用域指向的对象”,作用域是指函数内部,这里的箭头函数,也就是sayHello,所在的作用域其实是最外层的js环境,因为没有其他函数包裹;然后最外层的js环境指向的对象是winodw对象,所以这里的this指向的是window对象。
参考:
博文系列目录
- JavaScript 深入系列
- JavaScript 专题系列
- JavaScript 基础系列
- 网络系列
- 浏览器系列
- Webpack 系列
- Vue 系列
- 性能优化与网络安全系列
- HTML 应知应会系列
- CSS 应知应会系列
交流
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。