前言
之前错误地认为直接运行 fn() ,函数中的this就指向window,然后认为箭头函数中的this就一定指向window。其实不然,做题还是得深究其原理而不是总结所谓的规律。
上码:
name = 2
function obj() {
this.name = 1
this.fn = function() {
console.log(this.name)
}
this.fn1 = () => {
console.log(this.name)
}
}
const a = new obj()
a.fn()
a.fn1()
const fn = a.fn
const fn1 = a.fn1
fn()
fn1()
思路
做本题时看到箭头函数以及其执行方式毫不犹豫得出答案:1222,后面运行后得到的答案却是1121,即涉及到箭头函数的我都弄错了。最后总结了本题所涉及的三个知识点。
1. js new 一个对象的过程,发生了什么?
- 首先创建一个空对象
- 让空对象的__proto__指向构造函数
- 让构造函数的this指向空对象并执行
- 若构造函数返回一个对象,则返回该对象,否则返回新创的对象
根据该知识点,我们得知题目中的this.name
、this.fn
、this.fn1
中的this都指向新创的对象a
2. js 箭头函数中的this指向哪里?
指向父级作用域执行上下文,简而言之是指向父级作用域的this,且箭头函数的this指向不会改变。我们知道this指向是执行时才确定的,但是箭头含数压根没有自己的this,只会继承父级执行上下文的this,所以箭头函数的this是定义时就确定了的,而这里的this指向fn1前面的this,即指向a对象,所以a.fn1()
为a对象中的1,fn1()
中的this也是确定的指向实例对象a也是1
this.fn1 = () => {
console.log(this.name)
}
3.js 中this指向执行时才确定
正如2所说的,this指向除了箭头函数是不会改变的,其他的this都是执行时才能确定,例如a.fn()
,函数中的this指向调用它对象,对象的内容成为fn的执行上下文,所以结果为1;而fn()
=== fn.call(window)
,即调用者为window,所以window成为fn的执行上下文,所以结果为2
补充
当代码为以下情况时就为1222
name = 2
const a = {
name:1,
fn() {
console.log(this.name)
},
fn1:() => {
console.log(this.name)
}
}
a.fn()
a.fn1()
const fn = a.fn
const fn1 = a.fn1
fn()
fn1()
因为箭头函数的this的父级作用域是fn1所在的指向上下文,所以谁调用fn1,箭头函数的this就指向谁,即fn1()
的值为a中的name为1