thisの針を変える方法

3208 ワード

javascriptの大きな特徴:関数があります.
 
設定時のコンテキストの実行時のコンテキスト、
そして
文脈は変えられます.
例1:
function f(){
    console.log(this);
}
f();//window
call、appy
例2:
var aa={
    name:'zdn',
    fun:function(){
        console.log(this.name);
    }
}
var hhh={
    name:'hhh'
}
aa.fun.call(hhh);//hhh
aa.fun.apply(hhh);//hhh
callとappyは動的にthisを変えるために現れたものと見られていますが、一つのobjectにはある方法がありません.しかし、他には(本栗の中のaaにはfun方法があります)、calやappyを使って他の対象の方法で操作できます.
callとappyの違い
両者の作用は全く同じで、ただパラメータを受け取る方式が違っています.
例3:
var func=function(arg1,arg2){
    
};
func.call(this,arg1,arg2);
func.apply(this,[arg1,arg2]);
その中のthisはあなたが指定したい文脈です.彼はどのJavaScriptオブジェクトでもいいです.コールはパラメータを順番に渡す必要があります.
JavaScriptでは、ある関数のパラメータ数が固定されていませんので、適用条件といえば、あなたのパラメータが明確に数を知っているときにコールを使います.
不確定な時はappyでパラメータpshを配列に送ります.パラメータの数が不確定な場合には,関数内部もargmentsという配列によってすべてのパラメータを遍歴することができる.
call、appyのよく使う使い方
1.配列間の追加
var arr1=[1,2,3,4,5,6];
var arr2=['zdn',8,9];
Array.prototype.push.apply(arr1,arr2);
console.log(arr1);//[1, 2, 3, 4, 5, 6, "zdn", 8, 9]
2.配列間の最大値と最小値を取得する
var numbers=[1,23,4,5,677,678,90];
var max1=Math.max.apply(Math,numbers);//678
var max2=Math.max.call(Math,1,23,4,5,677,678,90);//678
3.
log方法を定義して、consolie.log方法を代行することができるようにします.
function log(){
    console.log.apply(console,arguments);
}
log(1);//1
log(12,30);//12,30
ビッド
bind()方法とcallとappy
似ています.変えられます.
手紙を変える
体内のthisの指差を数えます.
Bind()メソッドは、バインディング関数と呼ばれる新しい関数を作成します.このバインディング関数を呼び出すと、バインディング関数は、それを作成するために、最初のパラメータをthisとして入力します.
例4:
var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
bar(); // undefined
var func = bar.bind(foo);
func(); // 3
ここで新しい関数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(); //3
  
var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //3
注意:2回の出力3は、4,5が出力されていません.理由はjsの中で、複数回bind()は無効です.
より深いレベルの原因は、bind()の実装は、使用関数が内部で1つのcall/applyを包んだことに相当し、2番目のbind()は、もう1回のbind()を包むのに相当しますので、2回目以降のbindは有効になりません.
call、appy、bind比較
例5:
var o={
    name:'z'
};
var fun={
    sayName:function(){
        console.log(this.name);
    }
}

fun.sayName.bind(o());//  
fun.sayName.call(o);
fun.sayName.apply(o);
三つの出力は全部zですが、bind()の使い方を注意してください.彼の後ろには括弧が多くあります.
違いは、コンテキスト環境を変更したい場合には、直ちに実行するのではなく、コールバック実行する場合には、ビット()方法を使用することである.アプリ/callはすぐに関数を実行します.
 
まとめてみます
apply、call、bindの3つは関数を変えるためのthisオブジェクトの指向です.
apply、call、bindの3つの最初のパラメータはすべてthisが指す対象で、つまり指定したいコンテキストです.
apply、call、bindの3つは、後続のパラメータを利用して参照することができます.
bindは対応関数を返します.後で起動しやすくなります.apply、callはすぐ呼び出します.
いくつかのルールがあります.
ルール1:関数があるオブジェクトのkey値である場合、thisはこのオブジェクトを指します. 
ルール2:関数newがあると、オブジェクトを作成し、新しいオブジェクトを指します.
 
ルール3:call、bind、applyによって、thisの指向を変えることができます.
 
javascriptのthisは後期のバインディングと簡単に考えられます.ところがないときは、デフォルトでwindowと結びつけられます.