// 第四版 Function.prototype.bind2 = function (context) {
var self = this; var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fBound = function () { var bindArgs = Array.prototype.slice.call(arguments); return self.apply(thisinstanceof fNOP ? this : context, args.concat(bindArgs)); }
fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }
到此为止,大的问题都已经解决,给自己一个赞!o( ̄▽ ̄)d
三个小问题
接下来处理些小问题:
1.apply 这段代码跟 MDN 上的稍有不同
在 MDN 中文版讲 bind 的模拟实现时,apply 这里的代码是:
1
self.apply(thisinstanceof self ? this : context || this, args.concat(bindArgs))
多了一个关于 context 是否存在的判断,然而这个是错误的!
举个例子:
1 2 3 4 5 6 7 8 9 10 11
var value = 2; var foo = { value: 1, bar: bar.bind(null) };
functionbar() { console.log(this.value); }
foo.bar() // 2
以上代码正常情况下会打印 2,如果换成了 context || this,这段代码就会打印 1!
所以这里不应该进行 context 的判断,大家查看 MDN 同样内容的英文版,就不存在这个判断!
(2018 年 3 月 27 日更新,中文版已经改了😀)
2. 调用 bind 的不是函数咋办?
不行,我们要报错!
1 2 3
if (typeofthis !== "function") { thrownewError("Function.prototype.bind - what is trying to be bound is not callable"); }
3. 我要在线上用
那别忘了做个兼容:
1 2 3
Function.prototype.bind = Function.prototype.bind || function () { …… };
if (typeofthis !== "function") { thrownewError("Function.prototype.bind - what is trying to be bound is not callable"); }
var self = this; var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fBound = function () { var bindArgs = Array.prototype.slice.call(arguments); return self.apply(thisinstanceof fNOP ? this : context, args.concat(bindArgs)); }
fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }