Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.glorb.com!news.linkpendium.com!news.linkpendium.com!panix!not-for-mail From: kj Newsgroups: comp.lang.javascript Subject: (golf-ish) Conditional object property access Date: Mon, 2 Sep 2013 20:23:24 +0000 (UTC) Organization: none Lines: 101 Message-ID: NNTP-Posting-Host: panix3.panix.com X-Trace: reader1.panix.com 1378153404 15805 166.84.1.3 (2 Sep 2013 20:23:24 GMT) X-Complaints-To: abuse@panix.com NNTP-Posting-Date: Mon, 2 Sep 2013 20:23:24 +0000 (UTC) X-No-Confirm: yes User-Agent: nn/6.7.3 Xref: csiph.com comp.lang.javascript:21148 (WARNING: This is a "JavaScript golf"-type query, of little practical import; just for those who get into this sort of thing...) Quick version ============= How to shorten the generic JavaScript expression o.hasOwnProperty('p') ? o.p : ...while still preserving the *conditional* evaluation of the clause? (Here stands for an arbitrary JavaScript expression.) ---------------------------------------------------------------------- Leisurely version ================= I'm dealing with JavaScript code where expressions having the form above appear *all over*. Given the frequency of this pattern, it would be nice if JS had some special, and more succinct, syntax for it, e.g., something like: o['p':] ...where the "clause" would be evaluated (and returned as the value of the whole expression) *only if* o.hasOwnProperty('p') is false[1]. Absent such syntactic help, how can one shorten the pattern given above? The best that my noob-level JS can come up with is to define a helper function `HAS` (in a suitably restricted scope) to replace the verbose built-in hasOwnProperty, so that one can at least write: HAS(o, 'p') ? o.p : At the end of this post I give other alternatives I could think of, but they are all either *more* verbose than what they try to replace, or have some other weakness (e.g. failure to delay the evaluation of the clause). For the more expert JS coders out there: can one do better? ---------------------------------------------------------------------- Below are my various attempts: o.hasOwnProperty('p')?o.p: // the one to beat o['p':] // hypothetical/theo- // retical minimum? HAS(o,'p')?o.p: // my disappointing best GET(o,'p',) // evaluated // unconditionally GET2(o,'p',function(){return }) // ambiguous when the // value of o.p may be // a function GET3(o,'p',T(function(){return })) // T for Thunk function HAS(obj, prop) { return obj.hasOwnProperty(prop); } function GET(obj, prop, alt) { return HAS(obj, prop) ? obj[prop] : alt; } function GET2(obj, prop, alt) { return HAS(obj, prop) ? obj[prop] : alt(); } function Thunk (fn) { this.fn = fn } function T(fn) { return new Thunk(fn) } function GET3(obj, prop, alt) { return HAS(obj, prop) ? obj[prop] : alt instanceof Thunk ? alt.fn() : alt; } ---------------------------------------------------------------------- [1] The "delayed", or, more precisely, *conditional*, evaluation of the clause is an important aspect of the original expression's semantics, and is therefore one that any alternative formulation should retain. I point this out because the first alternative formulation that I came up with, the one using the helper function `GET`, turns out to fall short in this respect.