apply、call、bind他人の関数を借りる方法

7331 ワード

apply、call、bindapply call ネット上の文章は多いですが、多くはコピーして貼り付けて、しかも分かりにくいです.この文章を通じて、appy、call、bindに対する認識を明確に高めて、そしていくつかのそれらの効果を挙げて記憶を深めたいです.
appy、call
javascriptでは、callとappyは共に (context)のために存在し、換言すれば this のために存在する.
まず栗をください.
function fruits() {}

fruits.prototype = {
    color: "red",
    say: function() {
    console.log("My color is " + this.color);
}
}

var apple = new fruits;
apple.say(); //My color is red
しかし、もし私たちが対象のbana={color=0000 ff}、 banana= {color : "yellow"} , say , call apply apple say :があるなら、callまたはappyを通じてappleのsay方法を使うことができます.
banana = {
    color: "yellow"
}
apple.say.call(banana); //My color is yellow
apple.say.apply(banana); //My color is yellow
したがって、callとappyは動的にthisを変えるために現れたものであることが分かります.一つのobjectにはある方法がありません.しかし、他にはcallやappleによって他のオブジェクトを操作する方法があります.
見方(異なる角度):
  • fuits()は、カラー補正用の他の色付きポインタ
  • をプリントアウトした.
  • banaはsay()がないので、frits()のsay()を借りて印刷します.
    アプリとコールの違い
    applyとcallの両方にとって、役割は全く同じです.ただパラメータを受け取る方式は違います.例えば、次のような関数の定義があります.
    var func = function(arg1, arg2) {
    
    };
    
    以下のように呼び出すことができます.
    func.call(this, arg1, arg2);
    func.apply(this, [arg1, arg2])
    
    ( banana say )thisはあなたが指定したいコンテキストです.彼はいずれのJavaScriptオブジェクトでもいいです.call(this) apply(this) func() call .
    JavaScriptでは、ある関数のパラメータ数が固定されていませんので、適用条件としては、パラメータが明確に数を知っている場合はapply を使います.不確定な時はappyでパラメータpshを配列に送ります.パラメータの数が不確定な場合には,関数内部もargmentsという配列によってすべてのパラメータを遍歴することができる.
    記憶を深めるために、次のような使い方を挙げます.
    1、配列間の追加
    var array1 = [12 , "foo" , {name "Joe"} , -2458];
    var array2 = ["Doe" , 555 , 100];
    Array.prototype.push.apply(array1, array2);
    /* array1    [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
    
    call2、行列の最大値と最小値を取得する
    var numbers = [5, 458 , 120 , -215 ];
    var maxInNumbers = Math.max.apply(Math, numbers), //458
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
    
    array1 Array push number自体にはmax方法はありませんが、Mathはあります.私たちはcallまたはappyを利用してその方法を使うことができます.
    3、配列かどうかを検証する(前提はtoString()方法は書き換えられていない)
    functionisArray(obj){
        returnObject.prototype.toString.call(obj) === '[object Array]' ;
    }
    
    4、クラス(擬似)配列=>正真行列は配列方法を備えています.
    var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
    
    Javascriptには numbers Math max という名前があります.特に、 、または呼び出しarguments getElementsByTagNameなどがあり、document.childNodesに戻る.Aray下のプッシュ、ポップなどの方法は適用できません.
    アプリの使い方を深く理解し、call
    次は面接の問題を借りて、もっと深く理解してください.log方法を定義して、consolie.log方法をプロキシすることができます.よくある解決方法は:
    function log(msg) {
        console.log(msg);
    }
    log(1); //1
    log(1,2); //1
    
    上記の方法は最も基本的な需要を解決することができますが、NodeList を転送すると上記の方法は失効します.この場合、appyまたはcallを使用することを考慮してもいいです.ここ に注意してください.
    function log(){
        console.log.apply(console, arguments);
    };
    log(1); //1
    log(1,2); //1 2
    
    次の要求は、各logsメッセージに「(app)」を追加する前に中断することです.例えば、
    log("hello world"); //(app)hello world
    
    どうやって優雅にすればいいですか?この時、argmentsパラメータは擬似配列であり、Aray.prototype.slite.calを通じて標準配列に変換し、配列方法unshiftを使用する必要があります.
    function log(){
        //     =>      
        var args = Array.prototype.slice.call(arguments);
        args.unshift('(app)');
    
        console.log.apply(console, args);
    };
    
    ビッド
    appyとcallを言い終わったら、またbindについて話してください.bind()方法は、appyおよびcallと似ていても良い .MDNの説明は、applyと呼ばれる新しい関数を作成し、このバインディング関数を呼び出したとき、バインディング関数が作成されたときにBInd()方法の最初のパラメータをthisとして入力し、BInd()方法の2番目と以降のパラメータにバインディング関数を付けて動作するとき、自身のパラメータは、順番に元の関数のパラメータとして呼び出されるというものである.
    var foo = {
        bar : 1,
        eventBind: function(){
            var _this = this;
            $('.someClass').on('click',function(event) {
                /* Act on the event */
                console.log(_this.bar); //1
            });
        }
    }
    
    Javascript特有のメカニズムにより、文脈環境がeventBind:function(){}ドル('.someClass').on('click',function(event){}に移行しました.上記の使用変数はthisを保存するために有用であり、問題はありません.もちろんbind()を使うと、より優雅にこの問題を解決できます.
    var foo = {
        bar : 1,
        eventBind: function(){
            $('.someClass').on('click',function(event) {
                /* Act on the event */
                console.log(_this.bar); //1
            }.bind(this));
        }
    }
    
    上記のコードにおいて、bind()は、このclickイベントが呼び出されたときに結合された関数を作成し、そのthisキーワードは、入力された値(ここではbind()を呼び出すときに入ってくるパラメータ)に設定されます.したがって、ここに私たちは希望の文脈this(つまりfoo)を伝えて、bind()関数に入ります.そして、コールバック関数が実行されると、thisはfooオブジェクトを指します.簡単な栗をもう一つお願いします.
    var bar = function(){
        console.log(this.x);
    }
    
    bar(); // undefined
    var func = bar.bind(foo);
    func(); // 3
    
    this ここでは、新しい関数funcを作成しました.bind()を使ってバインディング関数を作成した後、実行されると、そのthisは私たちがbar()を呼び出す時のグローバルスコープではなくfooに設定されます.
    var bar = function(){
        console.log(this.x);
    }
    var foo = {
        x:3
    }
    var sed = {
        x:4
    }
    var func = bar.bind(foo).bind(sed);
    func(); //?
    
    var fiv = {
        x:5
    }
    var func = bar.bind(foo).bind(sed).bind(fiv);
    func(); //?
    
    答えは、期待の4と5ではなく、2回とも3を出力します.理由は、Javascriptで .より深いレベルの理由は、bind()の実装は、内部に1つのcall/applyを関数を使用することに相当し、第2番目のbind()は、第1回のbind()、 foo.bar bar() を再パッケージすることに相当する.
    apply、call、bind比較
    では、apply、call、bindの3つを比べたら、何か違いがありますか?いつappy、callを使いますか?いつbindを使いますか?簡単な栗です.
    var obj = {
        x: 81,
    };
    
    var foo = {
        getX: function() {
            return this.x;
        }
    }
    
    console.log( foo.getX.bind(obj)() ); //81   
    console.log( foo.getX.call(obj) ); //81
    console.log( foo.getX.apply(obj) ); //81
    
  • bind()コールバック関数は、関数bind()をすぐに実行する場合にのみ実行されます.
  • call()appy()直ちに実行関数が実行されます.
    3つの出力はいずれも81であるが、bind()方法を使用する bind() を参照してください.
    つまり、文脈環境を変えたいなら、すぐに実行するのではなく、折り返し実行する場合に、bind()を使用するのが違いです.アプリ/callはすぐに関数を実行します.
    もう少しまとめてみます
  • appy、call、bindの3つは、関数を変更するためのthisオブジェクトの指向です.
  • appy、call、bindの3つの最初のパラメータはいずれもthisが指すオブジェクト、すなわち指定したいコンテキストです.
  • appy、call、bindの3つは、後続のパラメータを使用して参照することができます.
  • bitは対応関数を返します.後で起動しやすくなります.apply、callはすぐ呼び出します.
  • Date:2017-02-18 Title:apple、call、bind Published:true Type:post Excerpt:https://mp.weixin.qq.com/s?__MzAxODE 2 MmjM-M 1 MA=&mid=2651551751515&idx=1&sn=a 5 d 0 dada 2 cccd 2 2 ccd 3 3 3 d 2 ccd 2 2 ccd 2 2 2 ccd 2 2 2 ccccd 2 2 2 2 2 cd 2 2 2 2 cccd 2 2 2 2 2 2 2 ccccd 2 2 2 2 2 2 2 2 2 ccccccccd 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f 2 2 2 2 2 2 2 f 2 f 2 f 2 f 2 f 2 f 2 f 2 f 2 f 2,72727878787878787878787878787878787878787878787878787878c 8283 a 661905 a 4025750 cab 6453175 a 3681 dc 230 a 661616 a c 04 d 027 f 453526666 d 23 eb 73995 a 0811 ad92 b 7732 d 6762&ascene=0&uin=MjUwNzcwOTcwma%3 D&devicetype=iMac+MacBook Pro 9%2+OX+10.11.6+build(15 G 31)&version=12010210&nettype=WIFI&fontScre=100&pass_ticket=SK 1 o 45 i 4 U 4 ySDW 3 GbsWpSAVQbhHCQ%2 BpjOcYU 99 sKxhrd% 2 FymPrGB 4 qWlbRJXGD