call和apply特点
- 传进去一个参数用来改变this指向
- 执行函数
function f1(){
console.log(this)
}
f1.call("hello") // [String: 'hello']
call实现原理
- 在Function原型链上声明一个函数myCall,传进去一个参数content,如果content不存在,则默认为window
- 在content上挂一个函数,指向this,这样调用这个函数相当于调用了外部函数,同时this指向content
- 接收剩余参数,用eval实现调用
- 删除content.fn
Function.prototype.myCall = function(content){
content = content?Object(content):window
content.fn = this; //这里的this是外部调用的函数,这里将外部的函数赋值给fn
let args = []
for(let i = 1;i<arguments.length;++i){
args.push('arguments['+i+']')
}
let r = eval('content.fn('+args+')') //直接调用fn函数,则this指向它的调用者,即content,同时数组会调用toString方法,将其元素展开
delete content.fn; //调用完之后,删除函数
return r;
}
function fn1(){
console.log(this)
console.log(arguments)
}
fn1.myCall("hello",1,2,3)
apply原理
apply跟call类似,传进去的是一个数组
Function.prototype.myApply = function(content,args){
content = content?Object(content):window
content.fn = this; //这里的this是外部调用的函数,这里将外部的函数赋值给fn
if(!args){
return content.fn();
}
let r = eval('content.fn('+args+')') //直接调用fn函数,则this指向它的调用者,即content,同时数组会调用toString方法,将其元素展开
delete content.fn; //调用完之后,删除函数
return r;
}
function fn1(){
console.log(this)
console.log(arguments)
}
// fn1.myCall("hello",1,2,3)
fn1.myApply("word",[1,2,3])
···