1.什么是call和apply?
对于js定义一个函数,如果不是对象的方法,那么它就是全局对象的函数。window对象身上的
例:
let obj = {
name: 'test',
getName: function() {return this.name}
}
//对象的方法
obj.getName();
funciton getName() { return 'aa'}
//window的方法
getName()
apply和call是一个方法 - 作用是改变函数调用的this指向
apply
let obj = {
getName: function () {return this.name}
}
let obj2 = {
name: 'zz'
}
//将obj的方法给obj2调用方法
obj.getName.apply(obj2) - 返回zz
call
let obj = {
getName: function () {return this.name}
}
let obj2 = {
name: 'zz'
}
//将obj的方法给obj2调用方法
obj.getName.call(obj2) - 返回zz
apply和call的区别
唯一的不同 - 方法接受的参数形式不用
call - 直接传参
apply- 数组形式传参
例如
let obj = {
getName: function(name,age) {return name + '' + age}
}
let obj1 = {}
obj.getName.call(obj1, 'aa', '1')
obj.getName.apply(obj1, ['aa', '1'])
如果第一个参数传null
在 JavaScript 严格模式下,如果 apply() 方法的第一个参数不是对象,则它将成为被调用函数的所有者(对象)。在“非严格”模式下,它成为全局对象。
2.手写call和apply
手写call
Function.prototype.mycall = funciton(obj) {
//是否传入对象,传入为当前对象否则为window
var obj = obj || window
// 赋值当前函数给func
obj.func = this
//将参数维数组转为真数组进行调用
obj.func(...([...arguments].slice(1)))
//还原对象,删除函数
delete func
}
手写apply
Function.prototype.mycall = funciton(obj) {
//是否传入对象,传入为当前对象否则为window
var obj = obj || window
// 赋值当前函数给func
obj.func = this
//将参数维数组转为真数组进行调用
obj.func(...arguments[1])
//还原对象,删除函数
delete func
}