Path: csiph.com!weretis.net!feeder4.news.weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: duplicator an array Date: Thu, 14 Apr 2016 22:09:43 +0200 Organization: PointedEars Software (PES) Lines: 115 Message-ID: <1593194.mKTEO0Afz8@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1460664584 9126 eJwNysERACEIA8CWQEiEcm7Q9F+Ct+9F0Dk7CSYEzWVTfg1r9XLxNCGP2X+MLgTTmLKoYp/vAQOJD8w= (14 Apr 2016 20:09:44 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Thu, 14 Apr 2016 20:09:44 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwNxMERACEIA8CWBEKYK0cN9F+Ct4/NoPEWmEROjlMuy47LPLa0dbxV4VEL3llDZ4NxMWeZUYY/icH9DR5JoRUf Cancel-Lock: sha1:0cAxp9mHzlcxM2Yuxxf0E/l+1Ns= X-NNTP-Posting-Host: eJwFwYEBwCAIA7CXFGit5wAb/59gAudmnyAYGEx+WB2jLNo1XdKy3EVsVR+aNTPCa8UvJR4ShhB0 Xref: csiph.com comp.lang.javascript:30278 Christoph M. Becker wrote: > On 14.04.2016 at 06:00, Aleksandro wrote: >> On 13/04/16 22:27, JRough wrote: >>> Okay, supposing the above works then I thought I would make an anonymous >>> function in the duplicator method. This would make it work the way the >>> problem was first outlined above. The only problem is how do I capture >>> the value of the two arrays? >>> >>> >>> I guess you would do something like Array.prototype.duplicator = >>> (function (){ >>> return this.concat(arr.slice(0)); >>> })() >> >> Try: >> >> Array.prototype.duplicate = function () >> { >> this.push.apply(this, this.slice(0)) >> } > > > The usual caveats wrt. augmenting built-in objects apply, though, see > e.g. > . It should be noted that the referred article is *old*; it is dated 2008-06-18. We now have String.prototype.trim(), and we have .toJSON() as a hook for JSON.stringify() in the language standard (ES 2015, § 24.3.2, step 12), and it is implemented. So it would seem that either Douglas Crockford was prophetic or, more likely, that his were good examples that later made it into the standard. JFTR, String.prototype.trim() has been in the FAQ for quite a while (currently in § 8.1), and I have written toJSON() methods. Also, one important reason for not augmenting the object referred to by Array.prototype, and by extension any prototype, has disappeared: we have standard property descriptors since ECMAScript Edition 5/5.1 (2009-12/2011-06) so that user-defined properties need no longer be enumerable and need not mess up for-in iteration (useful for sparse arrays if order is irrelevant): try { Object.defineProperty(Array.prototype, "duplicate", { value: function () { return this.concat(this.slice()); }, /* optional; the default for each attribute is “false” */ configurable: true, enumerable: false, writable: true }); } catch { console.warn("Array.prototype.duplicate cannot be (re)configured."); } In this case, however, there is little benefit of calling the method instead of inlining it with a.concat(a.slice()) [the 0 argument is optional as that is the implicit default (ES 2015, § 22.1.3.22, step 5)]. Also note that a.duplicate() as defined above does nothing of consequence; in order for it to duplicate the array items in the desired way it would have to define array items explicitly or its return value would need to be assigned to something. In any case, it is possible to safely augment built-in prototype objects if you limit the scope of the change: (function () { var arrayDuplicate = Array.prototype.duplicate; Array.prototype.duplicate = function () { return this.concat(this.slice()); }; /* do something */ Array.prototype.duplicate = arrayDuplicate; }()); This is safe only if there are no concurrent threads in the same global context as all share the same “Array” object and one of them might rely on a different implementation. DNS-based namespaces, as suggested in the article, might be a solution to that; but all parties involved have to agree to that for it to work reliably. Otherwise the only safe approach is to augment the instance instead of its prototype: (function () { var a = [1, 2, 3]; a.duplicate = function () { return this.concat(this.slice()); }; // … /* [1, 2, 3, 1, 2, 3] */ a = a.duplicate(); // … }()); -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.