梗概
- JavaScript函数执行的上下文(context)不是由函数定义的位置决定的,而是由函数调用的位置决定的
- 理解函数执行上下文对于掌握JavaScript中的[build::JavaScript this关键字]和闭包至关重要
关键特性
- 函数执行上下文决定了函数内部的
this指向 - 回调函数中调用另一个函数时,上下文是定义回调函数时的上下文,而非被调用函数定义的上下文
- 箭头函数与普通函数不同,它会保留定义时的上下文,不会创建自己的
this
示例
// 注册节点右键菜单事件
newGraph.on('node:contextmenu', ({ cell, e }) => {
handleNodeContextMenu(cell, e);
});在这个例子中:
- 回调函数
({ cell, e }) => { handleNodeContextMenu(cell, e); }中调用了handleNodeContextMenu函数 - 此时
handleNodeContextMenu函数的执行上下文是定义回调函数时的上下文 - 而不是定义
handleNodeContextMenu函数时的上下文
常见场景
1. 对象方法
const user = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`);
}
};
user.greet(); // 输出: "Hello, Alice" - this指向user对象
const greetFunc = user.greet;
greetFunc(); // 输出: "Hello, undefined" - this指向全局对象(或undefined在严格模式)2. 回调函数
const button = document.getElementById('myButton');
const user = {
name: 'Bob',
handleClick() {
console.log(`Button clicked by ${this.name}`);
}
};
// 错误方式
button.addEventListener('click', user.handleClick); // this会指向button而非user
// 正确方式1: 使用箭头函数
button.addEventListener('click', () => user.handleClick());
// 正确方式2: 使用bind
button.addEventListener('click', user.handleClick.bind(user));改变函数上下文的方法
- use::call
apply(thisArg, argsArray): 立即调用函数并指定this,参数以数组形式传入bind(thisArg, ...args): 返回一个新函数,this被永久绑定到指定值