一文带你了解JavaScript中的this问题

202 阅读3分钟

不管是面试,还是在日常的工作中;我们或多或少都会遇到这个问题,尤其是在面试过程中面试官都会问问this指向的一些问题,那么今天我们就来学习一下this的相关问题。

我目前处于离职状态,人在成都;如果看到这篇文章对你有用,正好你们公司在招人的话;可以内推一下,本人大专学历,找工作太难了。

我们先来看看这个示例,大家看看打印的结果是什么?

示例代码:1.1

let a = 'a';
function b () {
    const a = 'b';
    console.log(this.a);
}
b();

其实很多时候我们在看到这个问题的时候,我们的第一反应肯定是:b或者是a,其实都不对;打印的结果为:undefined;

是不是很疑惑,为什么是undefined,不是a或者b呢?你可以复制这个代码试试?

这儿不我先说明原因,后面再说原因。我们在看看下面这个示例:

示例代码:1.2

var a = 'a';
function b () {
    const a = 'b';
    console.log(this.a);
}
b();

大家先考虑一下示例代码1.2打印的是什么?

不慌我来告诉大家,这儿打印的是【a】,为什么改变了一下声明方式就有打印结果了呢?

这儿借用ES6官网说明:【var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩

这儿大家可以去看一下官方,我在这儿做一个简单解释:“顶层对象和全局变量挂钩在ES5中是一个设计缺陷,然后在es6中做了修改,如果你是用let或者const声明的变量将不会在挂载到window对象上面,也就导致我们用var声明的时候可以返回a,但是let的时候则返回undefined;”

然后我们在看看下面这个示例:

示例代码:1.3

大家看到这个代码,觉得应该打印什么呢?

let a = 'a';
function b () {
    var a = 'b';
    console.log(this.a);
}
b();

在这儿打印的还是undefined,至于原因嘛:就是b函数在window上,所以this所指向的是window,而window上是没有a的。

而b函数内的a是在b函数自己的作用域下所创建的不在window上,所以访问不到。后面有时间写一篇关于作用域的。

下面我们在看一个示例:

示例代码:1.4

var a = 'a';
function b() {
    var a = 'b';
    console.log(this.a);
}
let obj = {
    a: 'obj',
    d:b
}
obj.d();

我们在这儿可以看到,b函数是在obj对象中的;然后在全局去调用obj.d()函数;但是这儿的this指向是指向的obj,那么打印的结果:【obj】,当我们将obj中的a变量删除以后,大家在看看打印的是什么?这个算是一个小问题吧!不许去打印运行哈;然后将结果说道评论区。

示例代码:1.5

箭头函数

var a = 'a';
const b = () => {
    var a = 'b';
    console.log(this.a);
}
let obj = {
    a: 'obj',
    d: b
}
obj.d();

我们都知道箭头函数是没有他的this指向的,他是继承父级的this指向的,这个时候我们看到b箭头函数的父级是obj,而obj的this指向是window;所以...

打印的结果是:a

拓展箭头函数优势

  • 箭头函数没有自己的this
  • 箭头函数可以简写,不用return
  • 箭头函数不用function关键词
  • 箭头函数相对比较简洁

我想大家看到这儿,基本上this执行问题大致都了解了。至少面对常见的一些问题是可以应对或者回答的上了。