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
图个安心的话,可以通通上高逼格的箭头函数。:)
作者:寂寞的原子
链接:https://www.jianshu.com/p/45515682be0d