Skip to content

Instantly share code, notes, and snippets.

@clausreinke
Created July 12, 2013 21:11
Show Gist options
  • Save clausreinke/5987876 to your computer and use it in GitHub Desktop.
Save clausreinke/5987876 to your computer and use it in GitHub Desktop.
using _this=this to emulate arrow functions is fast but error-prone, requiring non-trivial analysis for use in transpilers. using .bind to emulate arrow functions is simpler, but slow in current engines. using an apply-based partial polyfill (bind) for .bind is fast in v8, slow in other engines.
// <script>
/* sample output
$ node ../bind-for-arrows.html
_this: 4ms
.bind: 25ms
bind: 4ms
_this, calls only: 1ms
.bind, calls only: 4ms
bind, calls only: 0ms
.bind, inline: 22ms
.call, inline: 0ms
.apply, inline: 4ms
20000 20000 20000 30000
*/
var obj1 = {
f: function () {
var _this = this;
return function (inc) {
_this.count+=inc;
}
},
count: 0
};
var obj2 = {
f: function () {
return function (inc) {
this.count+=inc;
}.bind(this);
},
count: 0
};
var obj3 = {
f: function () {
return function (inc) {
this.count+=inc;
};
},
count: 0
};
function bind(f,obj) {
return function() {
return f.apply(obj,arguments);
}
}
var obj4 = {
f: function () {
return bind(function (inc) {
this.count+=inc;
},this);
},
count: 0
};
console.time('_this');
for (i=0; i<10000; i++) obj1.f()(1);
console.timeEnd('_this');
console.time('.bind');
for (i=0; i<10000; i++) obj2.f()(1);
console.timeEnd('.bind');
console.time('bind');
for (i=0; i<10000; i++) obj4.f()(1);
console.timeEnd('bind');
var g1 = obj1.f();
console.time('_this, calls only');
for (i=0; i<10000; i++) g1(1);
console.timeEnd('_this, calls only');
var g2 = obj2.f();
console.time('.bind, calls only');
for (i=0; i<10000; i++) g2(1);
console.timeEnd('.bind, calls only');
var g4 = obj4.f();
console.time('bind, calls only');
for (i=0; i<10000; i++) g4(1);
console.timeEnd('bind, calls only');
console.time('.bind, inline');
for (i=0; i<10000; i++) obj3.f().bind(obj3)(1);
console.timeEnd('.bind, inline');
console.time('.call, inline');
for (i=0; i<10000; i++) obj3.f().call(obj3,1);
console.timeEnd('.call, inline');
console.time('.apply, inline');
for (i=0; i<10000; i++) obj3.f().apply(obj3,[1]);
console.timeEnd('.apply, inline');
console.log(obj1.count,obj2.count,obj4.count,obj3.count);
// </script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment