在 JavaScript 中,函数上下文通常指的是函数在执行时的当前对象的引用,这通常用 this
关键字表示。this
关键字在不同的执行上下文中可能引用到不同的对象。
1 全局上下文
当 this
关键字用在全局上下文(不在任何函数内部),它指向全局对象。
在浏览器中,全局对象是 window
。
console.log(this); // 输出: Window {...} (在浏览器环境下)
当你在 Node.js 环境下运行时,输出显示的是 Node.js 的全局对象。包含一系列 Node.js 环境下可用的全局函数和对象
console.log(this);
/<ref *1> Object [global] {
// global: [Circular *1],
//...
2 函数上下文
2.1 普通函数调用
- 当一个函数被直接(不作为对象的方法)调用时,
this
通常指向全局对象(在非严格模式下)function myFunc() { console.log(this); } myFunc(); //输出和前面直接console.log(this)一样
非严格模式下,默认this是全局变量
- 在严格模式 (
'use strict';
) 下,this
在函数调用中是undefined
function myFunc() { 'use strict'; console.log(this); } myFunc(); // 输出: undefined
2.2 方法调用
当一个函数作为一个对象的方法被调用时,this
指向调用该方法的对象
const myObj = {
myMethod() {
console.log(this);
}
};
myObj.myMethod();
//{ myMethod: [Function: myMethod] }
2.2.1 原型链
cat、dog这两个object没有say_hello这个function的,所以他们相当于先通过原型链“继承”了object,也即继承了object中的say_hello
之后调用say_hello当然就是cat和dog自己了,所以this指向的就是cat和dog
2.3 构造函数
当一个函数通过 new
关键字被调用(作为构造函数)时,this
指向新创建的实例对象。
function Car(make) {
this.make = make;
}
const myCar = new Car('Toyota');
console.log(myCar.make); // 输出: Toyota
3 call/apply——明确设置函数调用时的this值
这是之前我们用原型链的方式找到函数调用的this
可以使用apply或者call来设置调用时候的this值
3.1 apply和call的区别
call
方法接受一个具体的参数列表,并用这些参数来调用函数
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'Alice' };
greet.call(person, 'Hello', '!'); // 输出: Hello, Alice!
apply
只接受两个参数:一个是this
的值,另一个是一个数组(或类数组对象),该数组的元素将作为参数传递给函数
function greet(greeting, punctuation) {
console.log(greeting + ', ' + this.name + punctuation);
}
const person = { name: 'Alice' };
greet.apply(person, ['Hello', '!']); // 输出: Hello, Alice!