call、apply、bind 的原生实现

139 阅读1分钟

call 的实现

    Function.prototype.call = function(context) {
        context = context ? Object(context) : window;
        context.fn = this;
        let args = Array.from(arguments).slice(1);
        let res = eval("context.fn(" + args + ")");
        delete context.fn;
        return res;
    }
    function f1() {console.log(this)}
    function f2() {console.log(this)}
    f1.call(f2) // f2
    f1.call.call.call(f2)// window

apply 的实现


    Function.prototype.apply = function(context) {
        context = context ? context : window;
        context.fn = this;
        let args = Array.prototype.slice.call(arguments, 1);
        let res = eval("context.fn(args)");
        delete context.fn;
        return res;
    }

bind 的实现

  • bind 可以改变this指向
  • bind 不会直接执行,会返回一个函数(高阶函数)
  • 如果当前类被 new 了,this 应该指向当前类的实例
  • new 出来的方法可以访问原始类原型上的方法
    Function.prototype.bind = function(context) {
        let me = this;
        let args = Array.prototype.slice(1);
        function Foo() {}
        let fBind = function() {
            return me.apply(this instancof fBind ? this : context, args);
        }
        Foo.prototyoe = me.prototype;
        fBind.prototype = Foo.prototype;
        return fBind;
    }