参考链接: 手写call、apply、bind及面试题解析.
可以看看上面这篇文章,会好理解一点。
这里的解说犹如醍醐灌顶!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
Function.prototype.Mycall = function (context) {
// 判断context是否传入,如果未传入则设置window
context = context || window;
// 将调用函数设为对象的方法
// 这里的context.fn只是一个临时变量,
// fn最好是一个独一无二属性,以免覆盖原属性
// 这里的this是调用这个Mycall的函数 比如A.Mycall(person);
context.fn = this; // 这里相当于把这个函数 给context对象的fn属性
// 使得context对象也有这个函数方法
// 获取参数
var args = [...arguments].slice(1);
// 调用函数
var result = context.fn(...args);
// 将属性删除
delete context.fn;
return result;
};
function A(a) {
console.log(this.name);
console.log(a);
}
var person = {
name: "ssm",
}
A.Mycall(person,'a');
// ssm
// 1
console.log("------------------");
Function.prototype.Myapply = function (context) {
// 判断context是否传入,如果未传入则设置window
context = context || window;
// 将调用该Myapply的函数设为 对象的方法
context.fn = this;
// 获取参数
var args = [...arguments].slice(1);
var result = null;
// 调用函数 --- 用该对象的fn方法 调用,就相当于里面的this指向了context
if(args.length) {
result = context.fn(args);
}else {
result = context.fn();
}
delete context.fn;
return result;
}
A.Myapply(person, ['a','b']);
// [Array(2)]
// 0: (2) ["a", "b"]
// length: 1
// __proto__: Array(0)
</script>
</body>
</html>