T < x < B

Too long to tweet, too short to blog.
Oct 08
Permalink

Function/constructor duality

  • <cdleary-lappy> Waldo: what's the canonical way of detecting whether you're being called from a constructor?
  • <Waldo> um
  • <cdleary-lappy> s/from a/as a
  • <Waldo> cdleary-lappy: what's regexp_call do?
  • <Waldo> (it calls a common helper as I recall)
  • <cdleary-lappy> I meant in JS itself -- is there an idiom for that?
  • <Waldo> you can't
  • <Waldo> you can sometimes know you *weren't* called that way
  • <Waldo> but even then not always
  • <cdleary-lappy> what's the "not always" case?
  • <cdleary-lappy> (probably a discussion for #jslang, but w/e)
  • <Waldo> function C() { if (!(this instanceof C)) throw "not new"; }; var c = new C; C.call(c);
  • <cdleary-lappy> ah, tricky
  • <Waldo> function C() { if (!(this instanceof C) || this.constructed) throw "not new"; Object.defineProperty(this, "constructed", { value: true }); }; var c = new C; C.call(c) /* *will* throw */;
  • <Waldo> that's the only hackaround I know
  • <cdleary-lappy> Waldo: seems like reasonable usage will work with the simple instanceof test, though
  • <Waldo> yes
  • <cdleary-lappy> constructing an invoking separately was something I wasn't even aware of! :-)
  • <Waldo> it takes some work to get this in one's head
  • <cdleary-lappy> what's annoying about it, though, is that you need the constructor binding hack to get arguments in the constructor after the check
  • <cdleary-lappy> eh, I guess not, you can just make the two forms expect different arguments form, but it's still quite ugly