一、call函数
模拟实现第一步:整体思路
Function.prototype.call2=function(context){
context.fn=this; //1、将函数(谁调用 即this)设为对象(参数)的属性
context.fn(); //2、执行该函数
delete context.fn;//3、删除对象中的函数属性
}
模拟实现第二步:加上参数
Function.prototype.call2 = function(context) {
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']'); //// 执行后 args为 ["arguments[1]", "arguments[2]", "arguments[3]"]
}
eval('context.fn(' + args +')'); //这里 args 会自动调用 Array.toString() 这个方法。
delete context.fn;
}
模拟实现第三步:一些小问题
Function.prototype.call2 = function (context) {
var context = context || window; //this 参数可以传 null,当为 null 的时候,视为指向 window
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args +')'); //函数是可以有返回值的!
delete context.fn
return result;
}
Function.prototype.call = function (context, ...args) {
var context = context || window;
context.fn = this;
var result = eval('context.fn(...args)'); //采用ES6的语法
delete context.fn
return result;
}
二、apply函数
Function.prototype.apply = function (context, arr) {
var context = Object(context) || window;
context.fn = this;
var result;
if (!arr) {
result = context.fn();
}
else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn
return result;
}
Function.prototype.apply = function (context, arr) {
let context = context || window;
context.fn = this;
let result = eval('context.fn(...arr)');
delete context.fn
return result;
}