一、定义:
fun.call(thisArg, arg1, arg2...),call调用fun函数,thisArg是函数fun里的this指向;arg1、arg2为指定的参数列表。
fun.apply(thisArg, [arg1, arg2...]),apply调用fun函数,thisArg是函数fun里的this指向;arg1、arg2为指定的参数。
this始终指向的是最终调用它的对象:用call、apply调用的函数后,才能知道this具体指向的是什么。
两者的作用都是改变this指向,只是参数的传入方式不一样。
二、应用实例
1、统计调用了多少次parseInt()
var count = 0;
var oldParseInt = parseInt; // 保存原函数
// 自定义parseInt方法
window.myParseInt = function() {
// 计数
count += 1;
// 自定义parseInt没有接收实参,所以使用call或者apply调用原函数并传入参数,
// 无实际this指向时应用的是默认绑定规则,此处会绑定到全局对象上
return oldParseInt.call(null, ...arguments);
// return oldParseInt.apply(null, arguments);
};
myParseInt(2.3);
count;
2、调用父构造函数
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
// 让Product的this指向Food作用域,读取到Food里的name和price的值;也可以理解为Food继承Product
Product.call(this, name, price);
this.category = 'food';
}
new Food('sweetberry', 10);
3、调用函数并指定上下文的this
function greet() {
console.log('Hi,', this.name);
}
var obj = {
name: 'Jeo',
};
greet.call(obj); // greet的this.name读取到的是obj的name,即把this替换成obj
4、递归
const testArr = [
{
name: 'one',
children: [
{ name: 'one-one', },
],
},
{
name: 'two',
},
];
function fn(arr) {
if (arr && arr.length) {
for (const item of arr) {
console.log(item.name);
fn.call(this, item.children);
}
}
}
fn.call(this, testArr);
this都可替换成null,应用默认绑定规则,绑定当前作用域;可以理解为给fn传值并调用。是下面的等价替换。
function fn(arr) {
if (arr && arr.length) {
for (const item of arr) {
console.log(item.name);
if (item.children) {
fn(item.children);
}
}
}
}
fn(testArr);