FN.bind vs fn() { FN() }

266 views
Skip to first unread message

phidelta

unread,
May 28, 2012, 8:52:46 PM5/28/12
to nodejs
Hi all,

I have recently come to use .bind a lot, because it makes for very
clean code.

So rather than doing

<code>
var x; // this has some value that comes from prior code
setTimeout(function() { console.log(x) }, 5000);
</code>

I am now often doing

<code>
var x;
setTimeout(console.log.bind(console, x), 5000);
</code>

The question I have is: what is more performant? Is there any reason
to avoid .bind()?

Regards, Phil

mscdex

unread,
May 28, 2012, 9:28:35 PM5/28/12
to nodejs
On May 28, 8:52 pm, phidelta <philipp.dun...@gmail.com> wrote:
> The question I have is: what is more performant? Is there any reason
> to avoid .bind()?

IIRC there is a performance hit when using bind, but whether it will
seriously impact your application is something you'll have to test.

Mariusz Nowak

unread,
May 29, 2012, 6:27:05 AM5/29/12
to nod...@googlegroups.com
Use what works for you, and don't bother with premature optimization.

By the way it's not greatest bind use case, I wouldn't use bind here. In some older versions of node (v0.6.3 ?) , setTimeout passes one argument to the callback, and in your example it will be logged as well.

Oliver Leics

unread,
May 29, 2012, 6:56:55 AM5/29/12
to nod...@googlegroups.com
For me

setTimeout(function() { console.log(x) }, 5000)

is cleaner than

setTimeout(console.log.bind(console, x), 5000)

I used .bind() a lot to get rid of scope-problems for once and all
times. But then the code became, well, a mess: Everything I saw was
calls to .bind() ;-) Way too much noise. And it did not really solve
every scope-problem for once and all times.

Now I use .bind() when it is really necessary.
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en



--
Oliver Leics @ G+
https://plus.google.com/112912441146721682527

Felipe Gasper

unread,
May 29, 2012, 9:07:02 AM5/29/12
to nod...@googlegroups.com
(Slightly OT for this list, but...)

Just curious, was there, is there ongoing, a discussion of the prudence
of having a context object in the first place?

IMO, Perl does this the right way: the namespace/$this is just the first
argument that the function receives; i.e., $obj->func('foo') will
receive args of ( $obj, 'foo' ).

-FG

Matt

unread,
May 29, 2012, 9:51:41 AM5/29/12
to nod...@googlegroups.com
Hah, most people hate that about Perl. I always did. I much prefer having the implicit "this".


For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to

Tim Caswell

unread,
May 29, 2012, 11:23:56 AM5/29/12
to nod...@googlegroups.com
I don't think this part of JavaScript will ever change.  Node does not modify the JavaScript language it uses.

Lua does this though if you want to try luvit.io (node ported to lua).  It has syntax sugar to make defining and calling context-first methods easier.

    -- This is lua code, not JS
    local Point = {}

    -- constructor
    function newPoint(x, y)
      local obj =setmetatable({}, Point)
      -- This is really obj.initialize(obj, x, y)
      obj:initialize(x, y)
    end

    -- This is really Point.initialize = function (self, x, y) ...
    function Point:initialize(x, y)
      self.x = x
      self.y = y
    end


I think a more relevant question for the node list would be preference in using "this" and shared function prototypes vs storing state in closures.  I find both patterns very useful in node code and I often mix them.


For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to

Marco Rogers

unread,
May 29, 2012, 1:37:28 PM5/29/12
to nod...@googlegroups.com
I believe the current state of things is that the closure method of binding is optimized and very fast in v8. Function#bind is not. This is partly due to the fact that nobody uses it, so it may not be worth the time to optimize. But I agree with those that say do what works for you. Deal with performance when it becomes a problem. And don't try to second guess v8. It's probably smarter than you :)

One thing you could do, that think is more for code clarity than performance, is pre-bind any important objects.

Object.keys(console).forEach(function(key) {
  if(typeof console[key] === 'function') {
    console[key] = console[key].bind(console);
  }
});

Now you can just pass console.log anywhere and it will always be properly bound. Keep in mind that this hampers your ability to do call/apply, so use it sparingly. It also doesn't actually help your setTimeout example because you need to pass a value, YMMV :)

:Marco

Isaac Schlueter

unread,
May 29, 2012, 1:46:24 PM5/29/12
to nod...@googlegroups.com
fn.bind() is a bit slower than calling function () { fn() }, it's
true. But it's a difference between 5,000,000Hz and 10,000,000Hz. If
you're doing IO anywhere, an extra µs isn't going to affect
performance noticeably.

Write your program so that it's clear and readable. Then profile it.
Then make the silly micro-optimizations only where they matter.
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com

Marco Rogers

unread,
May 29, 2012, 2:55:58 PM5/29/12
to nod...@googlegroups.com
Wow, I remember bind being much slower than that a while back. Maybe some work has been done. Either way it proves the point. Don't assume you're better at optimizing js than v8 is.

:Marco

Scott González

unread,
May 29, 2012, 2:59:59 PM5/29/12
to nod...@googlegroups.com
On Tue, May 29, 2012 at 2:55 PM, Marco Rogers <marco....@gmail.com> wrote:
Wow, I remember bind being much slower than that a while back. Maybe some work has been done. Either way it proves the point. Don't assume you're better at optimizing js than v8 is.

Especially don't assume that you're better at optimizing today than v8 will be in the future.

Mark Hahn

unread,
May 29, 2012, 3:03:19 PM5/29/12
to nod...@googlegroups.com
Also, there have been situations where V8's advantage in one technique over another has reversed.  

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to

phidelta

unread,
May 29, 2012, 5:33:59 PM5/29/12
to nodejs
Thanks everyone!

I know my example was silly, this wasn't really about console log and
setTimeout, but rather about the pattern in general. I have fallen in
live with using bound functions as event listeners, since it allows me
to give them some context explicitly, rather than in a closure. I
wanted to know whether there is a huge downside and there seems not to
be one.

So my question has been fully answered and i will continue to use both
styles depending on the circumstance.

Thanks again and cheers,

Phil
Reply all
Reply to author
Forward
0 new messages