なぜ、この点を変更しますか?
私たちは、この点を変更するために使用されている適用役割バインド、呼び出しを知っている、なぜあなたはこの点を変更したいのですか?次の例を考えてみます。
var name="lucy";
let obj={
name:"martin",
say:function () {
console.log(this.name);
}
};
obj.say(); //martin,this指向obj对象
setTimeout(obj.say,0); //lucy,this指向window对象
通常の状況下では、この方法は、(ブラウザで)そのオブジェクトobjを呼び出し、このウィンドウオブジェクトのタイマーsetTimeoutメソッドがポイントにあると言うように指示されたと言う、これが原因でメソッドの発言である、ことを観察することができますタイマーはとても背地球環境の実現のコンテキストで実行されたときに実行されるメインスタックに実行されるコールバック関数、ですが、私たちは、この点を変更する必要があるので、私たちは、これはオブジェクトobjにポイントを言うことですアプローチする必要があります。
この方法を適用
2つのパラメータを受け付ける最初のパラメータは、この時点で、2番目のパラメータが関数であるパラメータは、アレイの形態で渡さ受け入れ、最初のパラメータがウィンドウにヌル、未定義、デフォルトである場合(に適用ブラウザ)、元の関数を変更する方法を適用するには、このポイントを使用直ちに実行されますが、この方法は、THI時点で唯一の一時的な変更です。
毎日の使用:この点を変更
例:
この点に関連したコールバック:
var name="martin";
var obj={
name:"lucy",
say:function(year,place){
console.log(this.name+" is "+year+" born from "+place);
}
};
var say=obj.say;
setTimeout(function(){
say.apply(obj,["1996","China"])
} ,0); //lucy is 1996 born from China,this改变指向了obj
say("1996","China") //martin is 1996 born from China,this指向window,说明apply只是临时改变一次this指向
ヒント:方法で渡されたパラメータを変更します
例:
配列の最大値を選択します:
var arr=[1,10,5,8,3];
console.log(Math.max.apply(null, arr)); //10
着信の形態では、パラメータとして直接ではない私たちができるようにアレイにMath.max(1,10,5,8,3)が、この方法は、アレイに適用することができますような、パラメータMath.max関数パラメータリストに基づいていますパラメータリストにパラメータがそれによって直接配列の最大値を選択し、渡されました。
呼び出し方法
この呼び出しの最初のパラメータは、方法に向けられ、それは、パラメータ(伝送パラメータとノート区別を適用)のリストが戻されます。パラメータがnullまたは(ブラウザ)で定義されていない、発現ポイントウィンドウであり、同一の呼この点一度のみ一時的な変更、および即時実行を適用します。
例:
var arr=[1,10,5,8,3];
console.log(Math.max.call(null,arr[0],arr[1],arr[2],arr[3],arr[4])); //10
リストの採用は、パラメータとして渡され、パラメータの配列として渡さ適用されます。
bindメソッド
バインドメソッド呼び出しと最初のパラメータに類似しているこの時点で、パラメータのリストが戻され(パラメータリストが、これは複数回通過することができ、一回の呼び出しがすべてのパラメータを渡さなければならない)が、この変更点の直後に実行するが、この機能は永久的な変化点を返していません。
例:
var arr=[1,10,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3])
console.log(max(arr[4])); //12,分两次传参
パラメータを渡すために、バインド複数の方法で見ることができるように、すべてのパラメータは、操作機能の実行の最後の関数の中に一緒に接続します。
バインド方法(面接の質問)を実装します。
Liteの
Function.prototype.bind=function () {
var _this=this;
var context=arguments[0];
var arg=[].slice.call(arguments,1);
return function(){
arg=[].concat.apply(arg,arguments);
_this.apply(context,arg);
}
};
パーフェクトバージョン
//实现bind方法
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
// this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(this instanceof fBound
? this
: oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 维护原型关系
if (this.prototype) {
// 当执行Function.prototype.bind()时, this为Function.prototype
// this.prototype(即Function.prototype.prototype)为undefined
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
};
var arr=[1,11,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3]);
console.log(max(arr[4])); //12
違いは、呼び出しを適用し、バインド3
- すべての3つの機能に、このターゲットポインタを変更することができます。
- このパラメータまたはパラメータなしで未定義またはnullの場合は最初の3つのパラメータは、それがグローバルウィンドウにデフォルトで、このオブジェクトを指しています。
- すべての3つのパラメータが転送されますが、コールはパラメータのリストがある一方で、配列を適用し、1回のコールを適用し、パラメータを渡し、バインド渡され、数回に分けることができますすることができます。
- バインドバインドは、後で呼び出しを容易にするため、この後リターンの関数であり、適用、呼び出しはただちに実行されます。