<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 最简化的版本
//1、将函数设为对象的属性 2、执行该函数 3、删除该函数
Function.prototype.call2 =function(context){
context.fn = this;
context.fn();
delete context.fn;
}
var foo={
name:'paopao'
}
function test(){
console.log(this.name);
}
// test.call2(foo);
// 不定长的参数,解决
Function.prototype.call3 = function(context){
context.fn = this;
var args = [];
for(let i=1;i<arguments.length;i++){
// 或者使用字符串进行拼接
args.push('arguments['+i+']');
//使用模板字符串
args.push(`arguments[${i}]`);
}
//eval能使字符串中的表达式像javascript的运行环境中一样去执行
eval(`context.fn(${args})`);
delete context.fn;
}
var foo1={
name:'hello china'
}
function test1(age,color){
console.log(this.name);
console.log(age);
console.log(color);
}
// test1.call3(foo1,12,'yellow');
//最终版:解决返回值的问题和this的参数为null,这个时候默认指向window
var name = 'ab';
function test2(){
console.log(this.name);
}
// test2.call(null)
Function.prototype.call4 = function(context){
var context = context || window;
context.fn = this;
var args = [];
for(let i=1;i<arguments.length;i++){
args.push(`arguments[${i}]`);
}
var res = eval(`context.fn(${args})`);
delete context.fn;
return res;
}
var name='lan paopao';
var foo4 ={
name:'paopao wudi'
}
function test4(age,color){
console.log(this.name);
return {
name:this.name,
age:age,
color:color
}
}
test4.call4(null);
console.log(test4.call4(foo4,1233,'hahha'));
</script>
</body>
</html>
ps:参照冴羽大佬