传说中面试热点必考的JavaScript的上下文this指向问题,我决定用心整理下
1、函数的关键字this表示函数的上下文
2、我要引用一下红宝书第四版里的话,并不是因为我懒,而是它写的太好了。
执行上下文的概念在JavaScript中是颇为重要的。变量或函数的上下文决定了它们可以访问哪些数据,以及它们的行为
全局上下文就是最外层的上下文。根据ECMAScript实现的宿主环境,表示全局上下文的对象可能不一样。在浏览器中,全局上下文就是我们常说的window对象,因此所有通过var定义的全局变量和函数都会成为window对象的属性和方法。
3、MDN
MDN的this
与其他语言相比,函数的
this
关键字在 JavaScript 中的表现略有不同,此外,在严格模式和非严格模式之间也会有一些差别。在绝大多数情况下,函数的调用方式决定了
this
的值(运行时绑定)。this
不能在执行期间被赋值,并且在每次函数被调用时this
的值也可能会不同。ES5 引入了 bind 方法来设置函数的this
值,而不用考虑函数如何被调用的。ES2015 引入了箭头函数,箭头函数不提供自身的 this 绑定(this
的值将保持为闭合词法上下文的值)。
那JavaScript里面的this到底指向谁呢?
可以粗糙的理解成,this的指向是在调用时确定的。细一点说,又有这么几点规则。
这是什么意思呢?
console.log(this);// window对象
function func1() {
console.log(this);
}
func1();// window对象
function func2() {
'use strict';
console.log(this);
}
func2();// undefined
这里要解释一下什么叫做隐式,
比如说,它是通过某个对象进行调用的,就像这样纸
function fn() {
console.log(this);
}
const girl = {
name: 'Yolanda',
age: 18,
func: fn
}
girl.func();// {name: "Yolanda", age: 18, func: ƒ}
那显式是啥样的,它一般就是通过call、apply、bind指定了明确的上下文,这个一两句说不清楚,后面有空再说叭
class People {
constructor(name, age){
console.log(this);// People {}
this.name = name;
this.age = age;
console.log(this);//People {name: "Yolanda", age: 18}
}
test() {
console.log(this);
}
}
const girl = new People('Yolanda', 18);
girl.test();// People {name: "Yolanda", age: 18}
这个call/apply/bind的作用就是这个,后面专门写博客说
这个看第二点的栗子
1、这里有一道面试题,关于箭头函数
const zhangsan = {
name: '张三',
sayHi() {
console.log(this)
},
wait() {
setTimeout(function() {
console.log(this)
})
}
}
zhangsan.sayHi()//zhangsan
let func = zhangsan.sayHi
func();//window
zhangsan.wait();//window
改成箭头函数
const lisi = {
name: '李四',
sayHi() {
console.log(this)
},
waitAgain() {
setTimeout(()=> {
console.log(this)
})
}
}
lisi.waitAgain();//lisi
2、哦对了,这里还经常会这样出题
就是我前面不是写了对象的调用咩
function fn() {
console.log(this);
}
const girl = {
name: 'Yolanda',
age: 18,
func: fn
}
girl.func();// {name: "Yolanda", age: 18, func: ƒ}
const temp = girl.func;
temp();// window对象
就是说如果是把这个函数保存成一个变量,再调用,那this指针就是window对象了
3、再看一个
var test = {
a: 1,
b: 2,
fn: function() {
// 只是定义还没调用的话,这里的this不知道指代的什么,因为函数只有被调用才能确定上下文
console.log(this.a + this.b);
console.log(this === test);
}
}
// 这样显示的就是NAN,因为这样调用的时候,this指代的是window对象
var fn = test.fn;
fn();
// 这样调用显示结果才是3
test.fn();
持续更新中ing…