一、call和apply的功能:
- 调用构造函数来实现继承
// 一个类
function Product(name,price){
this.name = name;
this.price = price;
}
function Food(name,price){
Product.call(this,name,price);
// 使得Food类有name属性和price属性,且值为new Food时传递进来的name和price
this.category = food;
}
const hotDog = new Food("旺财",20)
- 调用函数,且指定函数的上下文
function showName() {
console.log(this.id + ':' + this.name);
};
var obj = {
id: 1,
name: 'yuguang'
};
showName.call(obj)
// showName函数的this为obj对象
// 因此会输出 1:yuguang
- 单纯调用某函数
Math.max.call(null,1,2,3,4) //输出4
二、模拟实现call
call函数内部要调用一个函数,且将函数的this指向第一个参数,call函数最终要返回该函数调用的结果
// ...args表示剩余的参数被收集到名为args的数组中,且用展开运算符将数组展开了
Function.prototype.myCall(obj, ...args){
// 如果未传递第一个参数,则默认为全局对象
// this为null和undefined时,this也指向window
var content = obj || window;
/*
给obj添加一个属性,属性名func,属性值为myCall函数的this
(show函数调用myCall函数,this就指向show函数)
*/
content.func = this;
// 调用函数,并传递参数,用变量re接收函数调用的结果
const re = content.func(...args); // 保证了func的this指向content
// 删除obj的临时属性
delete content.func;
// 返回函数执行结果
return re;
}
给content添加属性时,最好别使用func
,用一个不太容易跟现有属性冲突的名字,如__tempFun__