学完了整个 JavaScript 基础篇章之后,今天重新总结复习一下 this 的用法。
除了绕晕新手以外,this
还是有其存在的价值,如果没有 this
,那么我们在写一个构造函数的时候,就不知道如何代指我们即将 new
出来的对象(因为事实上这个时候他并没有名字)。
|
|
但是实际上 this
却带来了很多副作用以及意想不到的用法,因此下面就来总结讨论一下 this 的值。
Key Points
this
是为了解决 一个函数获取一个对象的引用 这个问题this
必须在函数体的内部才有意义,否则等于window
- 可以对函数内的
this
进行 隐式指定 和 显式指定 - 箭头函数 没有
this
new
之后发生的 4 件事情
函数体外部的 this
this
必须在函数体的内部才有意义
如果 this
不在任何函数体内部的话,他的值是全局对象,当然在浏览器中就是 window
,因此如果不在函数体内部的话,就无从讨论 this
。
|
|
注意了!这里说的函数体内部要与函数的调用区分开来!最显然的是上面的 console.log(this.a)
的括号中的 this
并不是函数体内部的 this
,所以他也是没有意义的。
函数体内部的 this
函数内部
this
的值取决于函数被调用的方式
我们有两种方式可以调用函数并指定 this 的值:隐式指定 和 显式指定。
举个栗子,我们有这样一个对象:
|
|
然后想要调用其中的 greeting()
方法,我们可以 隐式指定 this
的值:
|
|
我们也可以 显式指定 this
的值:
|
|
看起来好像没什么区别?不,区别大了。
让我们再定义一个对象,就能看出其中的端倪。
|
|
我们现在可以这样调用 harvey
的 greeting
|
|
箭头函数的 this
箭头函数没有
this
如果我们把上面讨论的栗子中的函数改为箭头函数,那么他里面的 this
也就没有意义了,他的 this
具体的取值得向上一个函数找:
|
|
就算我们用 call
也无法指定 this
:
|
|
new 运算符
在我们使用 new
去创建新对象的时候,系统自动帮我们做了 4 件事情
- 自动创建空对象
- 自动为空对象关联原型,原型的地址为
X.prototype
- 自动将空对象作为
this
关键字运行构造函数 自动
return this
,也就是说可以接着写new X().getName()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
function Person(name, age){ this.name = name this.age = age } Person.prototype.greeting = function () { console.log(`Hello, I am ${this.name}`) console.log(this) } const harvey = new Person('harvey', 22) // 这里自动将 harvey 作为 this 运行了构造函数 harvey.greeting()
这里我自己尝试模拟了一下一个功能类似于 new
的函数
|
|
好了,this
的讨论结束,理解的关键就在于我们最开始提到的 5 点 Key Points。
再看看网上总结的 this
留坑,以后再总结。