yuanyuanbyte / Blog

圆圆的博客,预计写七个系列:JavaScript深入系列、JavaScript专题系列、网络系列、Webpack系列、Vue系列、JavaScript基础系列、HTML&CSS应知应会系列。
306 stars 125 forks source link

JavaScript 基础系列之 this 指向问题 #99

Open yuanyuanbyte opened 2 years ago

yuanyuanbyte commented 2 years ago

本系列的主题是 JavaScript 基础,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末

如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。

this 指向问题

全局环境中的 this

例子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

例子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对象。

参考:

查看全部文章

博文系列目录

交流

各系列文章汇总:https://github.com/yuanyuanbyte/Blog

我是圆圆,一名深耕于前端开发的攻城狮。

weixin