jsの深いcall、appyとbindのアナログは実現します.
6338 ワード
callとappyの役割:オブジェクトを別のオブジェクトに置き換える方法を呼び出します.違い:呼び出しパラメータの形式が違います.(callパラメータを順次与えて、applyはArayオブジェクトを通して伝えられました)this:私を呼び出した人は、まずコールの栗を見る人を指します.
var foo = {
value: 1
};
function fn() {
console.log(this.value);
}
fn.call(foo); // 1
注意:1、callはthisの指向を変えています.foo 2、fn関数で実行すれば上のコードを次のような形に変えられます.var foo = {
value: 1,
fn: function() {
console.log(this.value)
}
};
foo.fn(); // 1
fnをオブジェクトfooの属性として呼び出します.この関数をオブジェクトの属性に設定します.この関数のパラメータ処理に注意してください.2、この関数を実行します.3、この関数を削除します.したがって、コールのシミュレーションは以下の通り実現される.Function.prototype.myCall = function (context) {
var context = context || window; // this null, window
context.fn = this; // myCall , myCall,this , this
var args = []; //
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}// this , , 1
var result = eval('context.fn(' + args +')');//args Array.toString()
delete context.fn;
return result; //
}
applyの実現はcallと似ていますが、後のパラメータは配列です.実現方法は以下の通りです.Function.prototype.myApply = function (context, arr) {
var context = Object(context) || window;
context.fn = this;
var result;
if (!arr) { //
result = context.fn();
}
else {
var args = []; //
for (var i = 0, len = arr.length; i len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn;
return result;
}
bind:bind()メソッドは新しい関数を作成します.この新しい関数が呼び出されると、ビnd()の最初のパラメータはその動作時のthisとして使用され、その後のシーケンスパラメータはそのパラメータとして転送された実際の参照の前に渡されます.特徴:1.関数を返します.2.パラメータが入ることができます.この二つの特徴によって、下記のようにシミュレーションできます.Function.prototype.bind2 = function (context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
} // bind
var self = this; //self
var args = Array.prototype.slice.call(arguments, 1);// bind2
var fNOP = function () {
};
// , fbound.prototype = this.prototype
var fbound = function () {
self.apply(this instanceof self ? this : context,args.concat(Array.prototype.slice.call(arguments)));
}
// ,this ,self , true ,this
// ,this window,self , false ,this context
fNOP.prototype = this.prototype;
fbound.prototype = new fNOP();
// prototype prototype,
return fbound;
}