アナログはJavascriptの中のcallとappyを実現します.


Callのシミュレーション実現
call()メソッドは、指定されたthis値と個別に与えられた1つまたは複数のパラメータを使用して関数を呼び出します.
これはMDNのcallに関する説明です.分かりやすい言葉で説明してください.
  • により、this値が指定されました.
  • は、複数のパラメータ
  • に入ることができる.
  • オブジェクトを呼び出すとき関数
  • このように説明するかもしれませんが、まだ曖昧です.例を見てもいいです.
    function Test(name, age) {
        console.log(this.name);
        this.name = name;
        this.age = age;
    }
    
    var man = {
        name: 'Wei'
    };
    Test.call(man, 'Willem', 18); // Wei
    console.log(man.name); // Willem
    console.log(man.age); // 18
    Test関数でthis.nameを出力する前に、name属性がなかったが、Test.call(man, 'Willem', 18);を実行した後にWeiが出力された.man においてもage属性がなく、name属性の値はWeiであり、出力の値はWillemである.Test関数の実行中のthisの値はman を指し、call関数を介してTest関数にパラメータを伝えることができることを示している.
    これを分析してみると、一言にすぎない. call this 。.
    call関数を実現する前に、thisの方向をどう修正するかを考えられますが、実は簡単です.直接にターゲット関数を変更するコンテキストにマウントします.これに似ています
    var obj = {
        name: 'Willem',
        sayHi: function() {
            console.log(this.name);
        }
    };
    obj.sayHi(); /* Willem */
    コードはどうやって実現されますか?
    Function.prototype.wcall = function(context) {
        context = context || window; //    this ,   window
        context.__fn__ = this;
        var args = [];
        
        for (var i = 1, len = arguments.length; i < len; i++) {
            args.push('"'+ arguments[i] +'"');
        }
        
        var ret = eval('context.__fn__(' + args + ')');
        delete context.__fn__;
        
        return ret;
    }
    上記のコードには、関数を実行するためにevalが採用されています.もちろん、es 6の拡張演算子も同じ機能を実現することができます.evalまたはjsのタイプに慣れていない子供用の靴はevalのコードに疑問があるかもしれません.
    var args = ['a', 'b', 'c'];
    eval('context.__fn__(' + args + ')');
    
    //            
    
    //        js        ,         
    //     :'string ' + [1, 2]          +,             , join        
    //   'string' + [1, 2] === 'string 1,2'
    var str = 'context.__fn__(' + args + ')'; // === 'context.__fn__(a,b,c)'
    
    // eval()            JavaScript      
    // eval(str)           context.__fn__(a,b,c)
    //     a, b, c              
    //            args             ,wcall   :args.push('"'+ arguments[i] +'"')
    // args = ["'a'", "'b'", "'c'"];
    // 'context.__fn__(' + args + ')' === 'context.__fn__("a","b","c")'
    //           context.__fn__("a","b","c")
    eval(str);
    以上はコールの実現についてです.
    Appleのシミュレーション実現
    apply()メソッドは、与えられたthis値の関数として、配列(または同様の配列オブジェクト)として提供されるパラメータを呼び出します.
    原理などは多くなく、applyとcallの役割は同じです.違いはapplyはパラメータを配列として伝えます.callはパラメータを一つずつ入力します.直接コード:
    Function.prototype.wapply = function(context, args) {
        context = context || window;
        context.__fn__ = this;
        var ret;
        
        if (!args || !(args instanceof Array) || args.length === 0) {
            ret = context.__fn__();
        } else {
            var arr = [];
            for (var i = 0; i < args.length; i++) {
                arr.push('"' + args[i] + '"');
            }
    
            ret = eval('context.__fn__(' + arr + ')');
        }
    
        return ret;
    }
    以上がappyの実現についてです.
    もっと:tsシミュレーションを使って実現した部分JavaScript関数と属性