JavaScript在ES5中加了个Function.prototype.bind
,可以绑定当前对象,于是就不需要再放一个变量来保存this
了,在需要使用this
的情况下会很方便。
那么Function.prototype.bind
到底是怎么实现的呢?原生的实现先不说,Polyfill是我们可以看到的(参考MDN),像这样:
if (!Function.prototype.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 () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
不难看出,我们得到的其实是一个全新的函数!原函数被封装起来了,然后在调用的时候强制为它指定this
。
从结果上来看,浏览器原生的Function.prototype.bind
也是如此。
CoffeeScript的fat arrow(=>
)实现的绑定比这个轻量一些,但也是需要将原函数和当前对象存起来,并返回一个新的函数:
func = (a) => doSomething(a)
var func = (function(_this) {
return function(a) {
return doSomething(a);
};
})(this);
那么为什么不要滥用呢?
我测试了一下浏览器原生的Function.prototype.bind
,发现使用了bind
之后,函数的内存占用增加了近2倍!CoffeeScript实现的绑定稍微轻量一点,内存占用也增加了1倍多。
再顺便测试了下ES6新增的Arrow function(也是=>
),因为这个特殊函数是自带绑定技能的,结果惊奇地发现,它的内存占用和普通的Function
没啥区别。所以以后需要或者不需要bind
的场景如果一定要滥用bind
图个安心的话,可以通通上高逼格的箭头函数。:)
网友评论