JacaScript实现call apply bind函数

一、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;
}

猜你喜欢

转载自www.cnblogs.com/yyrecord/p/13386100.html