Hacker News new | ask | show | jobs
by Cushman 5039 days ago
> Or even by delegating to another object:

> viewInstance.onScroll = somethingElse.render;

This one is a bit dangerous, because as you mention the "methods" are just anonymous functions assigned to objects. If `render` is expecting to be called on a `somethingElse`, this might not work right without being bound.

2 comments

That's why I never use "this" in Javascript. For me, dropping any pretense of OOP allows me to write more elegant programs.
I think that's a pretty poor practice. It's actually counter to central idea of this article; that you should think with the language features. In situations like the one above, if you dont want to lose the context of "this" you can explicitly bind an object to be this and return the new bound function. See underscore's bind(). Its a little more verbose and clunky but it saves you from tossing out modular code.
I'm not so sure it's poor practice. Rich Hickey makes an excellent point about not confounding data and functions. And Javascript provides excellent structures for avoiding mutability altogether (if one wishes to) thanks to first-class functions. Javascript was always an amalgam of C-syntax, object-oriented "ideas", and functional "ideas". To "think with the language features" is to tie to together two disparate programming paradigms that in my opinion perform better independently than in combination. So I just happen to focus more on the functional aspects of Javascript (and CoffeeScript provides syntactic support to make this much easier).
Not poor practice in that Functional Programming is poor practice (it's great practice!). Poor practice in that JS is object oriented and JS engines optimize for OO style, see https://developers.google.com/v8/design for example. So avoid `this` if you don't care how fast your code runs.
> See underscore's bind()

Better, just use Function.prototype.bind, 0 bytes gzipped with Vanilla JS.

And of course, in CoffeeScript you would just use the fat arrow:

    somethingElse =
      render: => # do some rendering
Careful, that's not the same as (->).bind(somethingElse). => binds to the current value of this at execution-- in that function, @ will compile to `var _this = this`, not `somethingElse` as we'd expect.

I just tested and it looks like you can hack it by doing

  _this = somethingElse =
    render: => @renderMe # @ is somethingElse
but that is definitely a bug.
I've written some transpilers, and I nearly always use a "magic variable" like __this_12345 just to prevent problems like--umm--this. If every single one you use has a quasi-random number or string appended, a lot of headaches melt away.
Yeah, I apologize. I have changed it to read correctly.