javaScriptの深いcallの模擬は実現します.

2423 ワード

callの役割は2つあります.1.thisを変更します.2.関数を実行させます.
まずコールを使います.
var foo={
    value:1
}
function bar(){
    console.log(this.value)//1
}
bar.call(foo)
上記の例では、thisがfooを指し、barに実行させました.
次に重点シミュレーションに入り、コールを実現します.
上記のfooの対象を以下のように改造します.
var foo = {
    value: 1,
    bar: function() {
        console.log(this.value)
    }
};
foo.bar(); // 1
foo.bar()を呼び出してbarの中のthisがfooを指すのは簡単ですか?しかしこの時fooに属性を追加しました.これはいけません.心配しないでください.後でこの属性を削除します. 
だから私たちのシミュレーションステップは
  • は、関数をオブジェクトの属性に設定します.foo.fn=bar
  • はこの関数を実行します.foo.fn()
  • この属性を削除します.delete foo.fn
  • fnは対象の属性名で、いずれにしても最後に削除しますので、何でもいいです.
    だから構想はあって、私達は初版のcall関数を書くことができました.
    Function.prototype.call2 = function (context) {
     const fn = Symbol('fn');//        Symbol   ,       
     context[fn] = this;
     context[fn]()
     delete context[fn]
    }
    //     
    var foo = {
     value: 1
    };
    function bar() {
     console.log(this.value);// 1
    }
    bar.call2(foo); 
    callはパラメータも伝えられますので、例を挙げてください.
    var foo = {
     value: 1
    };
    function bar(name, age) {
     console.log(name)//kevin
     console.log(age)//18
     console.log(this.value);//1
    }
    bar.call(foo, 'kevin', 18);
     だから模擬は第二版を実現します.
    Function.prototype.call2=(context, ...args) {
     const fn = Symbol('fn');//        Symbol   ,       
     context[fn] = this;
     context[fn](...args)
     delete context[fn]
    }
     
    ここまでのcallのシミュレーションは80%を実現しました.
    しかし、三つの注意点があります.
        1.thisパラメータはnull、undefinedであり、nullとundefinedであるときは、windowを指していると見なされます.
         例を挙げます.
    var value = 1;
    function bar() {
        console.log(this.value);// 1
    }
    bar.call(null); 
    2.関数は戻り値があります.
    3.thisが基本タイプのデータに入ると、対象として包装されます.  
    だからアナログでcallの最終版を実現します.
    Function.prototype.call2=(context, ...args) {
     context=context?Object(context):window //Object       
     const fn = Symbol('fn');//        Symbol   ,       
     context[fn] = this;
     let result=context[fn]()
     delete context[fn]
     return result //      
    }
    ここではcallのシミュレーションが完了しました.ここでもう一つの問題を出して、callに対する自分の理解をテストします.
    function fn(){
        console.log(this)
    }
    function fn1(){
     console.log('100')
    }
    fn.call.call.call.call(fn1) ?
    次のセクションで「JavaScriptのbindのシミュレーション実現」を行います.問題を解いて答えを出します.まず自分で考えてみてください.
    var foo={
        value:1、
        bar:function(){
            consolie.log(this.value)
        }

    foo.bar()//1