bind Polyfill詳細解javascript bind
3321 ワード
前端面接でよく出会う面接の質問です.手書きで書く
この文章はECMAScriptの中のbind Polyfillについてbind方法を詳しく説明します.詳しくはMDNを参照してください.
まず、
プリセットパラメータ
ここにもう一つのポイントがあります.
このような書き方は、
bind
の方法です.この文章はECMAScriptの中のbind Polyfillについてbind方法を詳しく説明します.詳しくはMDNを参照してください.
まず、
bind()
call()
apply()
はjavascriptのthis
と密接に関係しています.彼らは共通の役割を持っています.つまり、thisオブジェクトに対して明示的に結合しています.bind()
は何をするものですか?bind()
方法会==新しい関数を作成します.bind()
が呼び出されたとき、新しい関数のthis
はbind()
の最初のパラメータに指定されます.残りのパラメータは新しい関数のパラメータとして呼び出されるときに使用されます.const obj = {
name: 'lily',
getName: function() {
return this.name
}
}
let fn = obj.getName
console.log(fn()) // undefined fn this [object Window]
let fn2 = fn.bind(obj, 1, 2, 3)
console.log(fn2()) // 'lily' bind() this obj
bind()
文法fn.bind(obj, arg1, arg2 )
this指向を変更する以外に、bind()は他の用途があります.プリセットパラメータ
ここにもう一つのポイントがあります.
bind
の最初のパラメータがnull
またはundefined
の場合、呼び出しの関数this
は、非厳密なモードでwindow
を指し、厳格なモードではTypeError: this is undefined
をエラーとします.function preset() {
return Array.prototype.slice.call(arguments)
}
let list1 = list(1, 2, 3) // [1, 2, 3]
let presetList = list.bind(null, 666)
let list2 = presetList() // [666]
let list3 = presetList(777, 888, 999) // [666, 777, 888, 999]
bind()
Polifillこのような書き方は、
new funcA.bind(thisArg, args)
オペレータがnew
ポインタを変更してもよく、優先度が一番高いので、コンストラクションthis
では使用できない.if (!Function.prototype.bind) (function() { // bind
let slice = Array.prototype.slice // slice
Function.prototype.bind = function() {
let thatFunc = this, // bind
thatArg = arguments[0], //
args = slice.call(arguments, 1) //
if (typeof thatFunc !== 'function') { // bind() , bind
throw new TypeError('only Function can be bound')
}
return function(){
let funcArgs = args.concat(slice.call(arguments)) // , bind ,
return thatFunc.apply(thatArg, funcArgs);
}
}
})()
下の書き方はnew funcA.bind(thisArg, args)
に使えます.if (!Function.prototype.bind) (function(){ // bind
var ArrayPrototypeSlice = Array.prototype.slice; // slice
Function.prototype.bind = function(otherThis) {
if (typeof this !== 'function') { // bind() , bind
throw new TypeError('only Function can be bound');
}
let baseArgs= ArrayPrototypeSlice .call(arguments, 1), //
baseArgsLength = baseArgs.length, //
fToBind = this, // bind
fNOP = function() {}, //
fBound = function() { //
baseArgs.length = baseArgsLength; // reset to default base arguments
baseArgs.push.apply(baseArgs, arguments); //
return fToBind.apply(
// new , this bind this
fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
);
};
if (this.prototype) {
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP(); // new
return fBound;
};
})();