call和apply的用法
MDN:
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
两者的区别:call()方法接受多个单独的参数,apply()方法接受一个包含多个参数的数组。
function fn(name, age) {
this.name = name
this.age = age
console.log(this) // window
}
fn.call({a: 1}, 'xiaoming', 13) // {a: 1, name: "xiaoming", age: 13},此时函数的this即是{a:1}
fn.apply({b:2}, ['xiaohong', 14]) // {b: 2, name: "xiaohong", age: 14}
作用1:实现构造函数的继承
function Product(name, price) {
this.name = name
this.price = price
}
function Food(name, price) {
Product.call(this, name, price)
this.category = 'food'
}
let f1 = new Food('面包', 12)
console.log(f1) // {name: "面包", price: 12, category: "food"}
作用2:调用匿名构造函数
let carLists = [
{ make: '大众', year: '2021'},
{ make: '奥迪', year: '2020'},
{ make: '别克', year: '2019'},
]
for(let i = 0, len = carLists.length; i<len; i++) {
(function(i) {
console.log(`${i}、${this.make}(${this.year})`)
}).call(carLists[i], i)
}
手动实现call
// 在方法的原型上定义一个自己的方法
Function.prototype.myCall = function () {
let args = [...arguments]; // 获得所有参数
let _this = args[0]; // 获得第一个参数,即传入的指定this值
_this.fn = this; // 因为是fn调用的myCall,所以myCall的this是fn
_this.fn(...args.slice(1)); // 调用fn,因为是_this调用的fn,所以fn的this是_this,并将后面的参数传进去
delete _this.fn; // 把fn这个方法删除
return _this; // 返回this
};
function fn(name, age) {
this.name = name;
this.age = age;
}
// 测试一下
console.log(fn.myCall({ a: 1 }, "xm", 10)); // {a: 1, name: "xm", age: 10}
apply实现只需将上面的_this.fn(...args.slice(1))
改成_this.fn(...args[1])
;