一、作为函数调用
- 非严格模式下的调用上下文(
this
的值)是全局对象,严格模式this
为undefined
function myFunction() {
return this;
}
myFunction(); // 返回window对象
二、作用方法调用
- 调用上下文为当前对象,即
this
指向当前对象
var calculator = {
value1: 1,
value2: 1,
add: function() {
// this指代当前对象
this.result = this.value1 + this.value2;
}
};
calculator.add() // 调用add方法结算结果
calculator.result // =>2
// 方括号(属性访问表达式)进行属性访问操作
calculator["add"]()
- 嵌套函数作为函数调用,非严格模式下
this
是全局对象,严格模式下为undefined
var o = {
m: function() {
var self = this; // 将this的值进行保存
console.log(this === o); // "true"
f(); // 调用嵌套函数f()
function f() {
console.log(this === o); // "false": this的值为全局对象或`undefined`
console.log(self === o); // "true": self指向外部函数this的值
}
}
}
三、构造函数调用
- 如果函数或者方法调用之前带有
new
关键字,它就构成构造函数调用。 - 构造函数调用会创建一个新的空对象,并初始化这个新创建的对象,将这个对象用作其调用上下文。
var o = {
m: function() {
return 1;
}
}
console.log(new o.m() === 1) // "false"
在上面的代码中,尽管构造函数看起来像一个方法调用,但它依然会使用new
出来的新对象作为调用上下文。也就是说,在表达式new o.m()
中,调用上下文并不是o
。
四、间接调用
call()
方法和apply()
方法
call()
和 apply()
是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数是要调用函数的母对象,它是调用上下文。
function myFunction(a, b) {
return a * b;
}
myObject = myFunction.call(myObject, 10, 2); // 返回 20
function myFunction(a, b) {
return a * b;
}
myArray = [10, 2];
myObject = myFunction.apply(myObject, myArray); // 返回 20
tip:
call()
和apply()
区别在于第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)- 在严格模式下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。
- 在非严格模下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。
结尾
系列文章: