在本教程中,您将了解 JavaScript call()
方法以及如何更有效地使用它。
JavaScript call()方法介绍
在 JavaScript ,函数是 Function
类型的实例。例如:
function add(x, y) {
return x + y;
}
console.log(add instanceof Function); // true
Function.prototype
有 call()
并具有以下语法的方法:
functionName.call(thisArg, arg1, arg2, ...);
在此语法中,functionName
的 call()
方法使用参数 arg1
, arg2
, … 和 thisArg
对象参数设置函数内部 this
对象,然后调用 functionName
函数。
thisArg
是functionName
函数内部this
对象引用的对象。arg1
,arg2
... 是传递给functionName
参数.
call()
方法调用 functionName()
并返回 functionName()
函数的结果。
下面的例子定义 add()
函数并正常调用它:
function add(x, y) {
return x + y;
}
let result = add(10, 20);
console.log(result); // 30
下面改用 call()
方法调用 add()
函数:
function add(x, y) {
return x + y;
}
let result = add.call(this, 10, 20);
console.log(result); // 30
默认情况下,函数内部的 this
的值设置为全局对象,即在 Web 浏览器的 window
和Node.js 的 global
。
请注意,在严格模式下,this
函数内部设置为undefined
而不是全局对象。
考虑以下示例:
var greeting = 'Hi';
var messenger = {
greeting: 'Hello'
}
function say(name) {
console.log(this.greeting + ' ' + name);
}
在 say()
函数内部,我们引用 this
的 greeting
。如果您只是通过 call()
方法调用函数,如下所示:
say.call(this,'John');
它将向控制台显示以下输出:
"Hi John"
但是,当您调用 say
函数对象的 call()
方法并传递 messenger
对象作为 this
值时:
say.call(messenger,'John');
输出将是:
"Hello John"
在这种情况下,say()
函数内部 this
的值引用 messenger
对象,而不是全局对象。
使用 JavaScript call() 方法链接对象的构造函数
您可以使用 call()
方法链接对象的构造函数。考虑以下示例:
function Box(height, width) {
this.height = height;
this.width = width;
}
function Widget(height, width, color) {
Box.call(this, height, width);
this.color = color;
}
let widget = new Widget('red', 100, 200);
console.log(widget);
输出:
Widget { height: 'red', width: 100, color: 200 }
在这个例子中:
- 首先,使用
height
和width
两个属性初始化Box
对象:。 - 然后在
Widget
对象的内部调用Box
对象的call()
方法,给this
的值设置为Widget
对象。
使用 JavaScript call() 方法进行函数借用
以下示例说明如何使用 call() 方法来借用函数:
const car = {
name: 'car',
start() {
console.log('Start the ' + this.name);
},
speedUp() {
console.log('Speed up the ' + this.name);
},
stop() {
console.log('Stop the ' + this.name);
},
};
const aircraft = {
name: 'aircraft',
fly() {
console.log('Fly');
},
};
car.start.call(aircraft);
car.speedUp.call(aircraft);
aircraft.fly();
输出:
Start the aircraft
Speed up the aircraft
Fly
代码是如何运行的。
首先,定义一个汽车对象,汽车对象具有一个属性 name 和三个方法、speedUp
,start和 stop
:
const car = {
name: 'car',
start() {
console.log('Start the ' + this.name);
},
speedUp() {
console.log('Speed up the ' + this.name);
},
stop() {
console.log('Stop the ' + this.name);
},
};
其次,定义飞机对象,它有一个属性 name 和一个 fly 方法:
const aircraft = {
name: 'aircraft',
fly() {
console.log('Fly');
},
};
三、调用 car 对象的 start, speedUp方法和 aircraft 对象的 fly 方法。但是,使用 aircraft 作为第一个参数传递 start 和 speedUp 方法:
car.start.call(aircraft);
car.speedUp.call(aircraft);
aircraft.fly();
在 start()
和 speedUp()
方法中,this
引用 aircraft
对象,而不是 car
对象。因此,this.name
返回 'aircraf'
字符串。因此,这些方法输出以下消息:
Start the aircraft
Speed up the aircraft
从技术上讲,aircraft
对象借用 car
对象的start()
和 speedUp()
方法。而函数借用是指一个对象使用另一个对象的方法。
下面的例子说明 arguments
对象是如何借用Array.prototype
的 filter()
方法,使用函数 call()
方法:
function isOdd(number) {
return number % 2;
}
function getOddNumbers() {
return Array.prototype.filter.call(arguments, isOdd);
}
let results = getOddNumbers(10, 1, 3, 4, 8, 9);
console.log(results);
输出:
[ 1, 3, 9 ]
如何运行的。
首先,定义 isOdd()
函数如果数字是奇数则 isOdd()
函数返回 true:
function isOdd(number) {
return number % 2;
}
其次,定义接受任意数量参数并返回仅包含奇数的数组的函数 getOddNumbers()
:
function getOddNumbers() {
return Array.prototype.filter.call(arguments, isOdd);
}
在这个例子中,arguments
对象借用 Array.prototype
对象的 filter() 方法。
最后、调用 getOddNumbers()
函数:
let results = getOddNumbers(10, 1, 3, 4, 8, 9);
console.log(results);
结论
在本教程中,您了解了 JavaScript call()
方法以及如何更有效地使用它。