bind 实现

用法

MDN bind

极简实现

1
2
3
4
5
6
Function.prototype.bind = function(obj, ...args) {
var fn = this;
return function() {
return fn.apply(obj, args)
}
}

简易实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Does not work with `new funcA.bind(thisArg, args)`
if (!Function.prototype.bind) (function(){
// Is this an error? We are invoking <call.bind> method before it's defined.
var slice = Array.prototype.slice.call.bind(Array.prototype.slice);
Function.prototype.bind = function() {
var thatFunc = this, thatArg = arguments[0];
var args = slice(arguments, 1);
if (typeof thatFunc !== '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');
}
return function(){
var funcArgs = args.concat(slice(arguments))
return thatFunc.apply(thatArg, funcArgs);
};
};
})();

复杂实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Yes, it does work with `new funcA.bind(thisArg, args)`
if (!Function.prototype.bind) (function(){
var ArrayPrototypeSlice = Array.prototype.slice;
Function.prototype.bind = function(otherThis) {
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 baseArgs= ArrayPrototypeSlice .call(arguments, 1),
baseArgsLength = baseArgs.length,
fToBind = this,
fNOP = function() {},
fBound = function() {
baseArgs.length = baseArgsLength; // reset to default base arguments
baseArgs.push.apply(baseArgs, arguments);
return fToBind.apply(
fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
);
};

if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();

return fBound;
};
})();

参考实现

https://github.com/Raynos/function-bind/blob/master/implementation.js

评论