yuanyuanbyte/Blog

JavaScript 基础系列之 this 指向问题

yuanyuanbyte opened this issue · 0 comments

本系列的主题是 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

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

weixin