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