Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #14384
| Path | csiph.com!usenet.pasdenom.info!gegeweb.42!gegeweb.eu!nntpfeed.proxad.net!proxad.net!feeder2-2.proxad.net!newsfeed.arcor.de!newsspool3.arcor-online.net!news.arcor.de.POSTED!not-for-mail |
|---|---|
| Content-Type | text/plain; charset="UTF-8" |
| Message-ID | <9708336.O9o76ZdvQC@PointedEars.de> (permalink) |
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
| Reply-To | Thomas 'PointedEars' Lahn <cljs@PointedEars.de> |
| Organization | PointedEars Software (PES) |
| Date | Thu, 07 Jun 2012 20:17:20 +0200 |
| User-Agent | KNode/4.4.11 |
| Content-Transfer-Encoding | 8Bit |
| X-Face | %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&.<b';Md8`dH6iqhT)6C^.Px|[=M@7=Ik[_w<%n1Up"LPQNu2m8|L!/3iby{-]A+#YE}Kl{Cw$\U!kD%K}\2jz"QQP6Uqr],./"?;=4v |
| Face | iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEXTxa4RFk5dUWANED8PFEfy7+MGBiW+n3ZNF/QuAAACaElEQVQ4jVXUwVOcMBQG8Dc7Rc4PUntdWV2uxjDpGaGeozOp1woar4jd5t/v9wLstMwsA/ntlxdCAgUc1hjTc9/JCZfGoo3wG3HdmdAWrIJRHe7GM/TmpY5VFefuVcAkkPbLIaN8rmPmjloyZxgyR3GuJ4K0AGtJ2htz8o7yqikm759fldQXaMpbDzjKAG+8v+AugVTOPO5DOjLvGtUYQwh0CPjnVMyGd+8/GfUB5nLKJDD2aLDh5HYyMDJGDwQIo2ZmZcKbowNmAdB/AzyFhrmF2MHRb0QJJfaAnwGB6orZhoykLzJtGwF/xpYxI1dswomiUj3gTuAIqCn/4C7cULwGNBtwMTk3Y4LfKB5YUaOKBKYtpplm7u0vip8tU1NWWyI/7XdcSuIDoMt6rVHMWT0DbjHPGqDqZVSa6zleLcUTcIKLoMv3ueJluALtAo9B302zPPlrtiVScRdCjXvVh3e3JpYa/jjkuC9N+LrBMlz/eAN4eQijX2EdLo6c5tGGHwLyHFtXk89dDGHwCVhG9T0S/j55AhRZgkMCmUQXJ49TnS1wnQDvw0eAh9ICeMmEFbCnPMFzjAvsWoEWEFdYEx+S0MoUZ1gT1wId8+AF3Bl2OoEu906AUHx5VLw/gXYg/x84loOah/2UYNrgiwSwGO7RfUzVBbx/kgpckumGOi6QirtD6gkLTitbnxNol47S2jVc2vsN5kPqaAHT8uUdAJM4v/DanjYOwmUjWznGfwB7sGtAtor5BgofDuzaRj4kSQAqDakTsKORa3Q3xKi3gE1fhl71KRMqrdZ2AWNNg/YOhQyrVBnb+i+nEg4bsDA+egAAAABJRU5ErkJggg== |
| Subject | Array.prototype.splice implementation in 'JS: The Good Parts' (was: Array.splice implementation in 'JS: The Good Parts') |
| Newsgroups | comp.lang.javascript |
| References | <921eeaac-96e3-440b-b023-20bd8a37f049@d17g2000vbv.googlegroups.com> |
| Followup-To | comp.lang.javascript |
| MIME-Version | 1.0 |
| Lines | 188 |
| NNTP-Posting-Date | 07 Jun 2012 20:17:21 CEST |
| NNTP-Posting-Host | 5b58087c.newsspool1.arcor-online.net |
| X-Trace | DXC=beP?e@;QBSM2jYf>V4L0gLic==]BZ:afN4Fo<]lROoRAnkgeX?EC@@@KPeR?^YhTLGDZm8W4\YJNLUFDj8T]K0?CDmniOZG;K0KnaFb4R7DVmH |
| X-Complaints-To | usenet-abuse@arcor.de |
| Xref | csiph.com comp.lang.javascript:14384 |
Followups directed to: comp.lang.javascript
Show key headers only | View raw
Jun Woong wrote:
> Is an implementation of Array.splice by Douglas Crockford correct?
You mean Array.*prototype*.splice. The difference is important; the
prototype property is *implicitly* inherited, the other property is not.
> When the implementation composes a resulting array (that is made up
> of elements deleted from the original array), it checks if each
> element exists:
>
> element = this[start + k];
> if (element !== undefined)
This error-prone, incompatible approach [1] is unsuited to determine if an
element with a certain index exists in an array (generally: if an object has
or inherits a property with a certain name), because an array element (a
property) may be (may have) the `undefined' value. The less error-prone,
but equally compatible/incompatible approach [1] is
if ((start + k) in this)
{
// …
}
or, where inheritance should *not* be considered,
if (this.hasOwnProperty(start + k))
{
// …
}
> result[k] = element;
>
>
> This gives an empty array (that is, []) for
>
> a = []; a[2] = 0;
> b = a.splice(0, 2); // b.length === 0
The method call means: "At index 0 of the array, remove 2 elements from the
array and return a reference to an Array instance having only the *removed*
elements as its elements."
Therefore, `b.length' should be 0.
> while the v8 implementation gives [undefined, undefined] (thus, the
> length of the result is 2).
>
> What does the ECMA standard says about this?
<http://ecma-international.org/ecma-262/5.1/#sec-15.4.4>:
| 15.4.4.12 Array.prototype.splice (start, deleteCount [ , item1 [ , item2 [
| , … ] ] ] )
|
| When the splice method is called with two or more arguments start,
| deleteCount and (optionally) item1, item2, etc., the deleteCount elements
| of the array starting at array index start are replaced by the arguments
| item1, item2, etc. An Array object containing the deleted elements (if
| any) is returned. The following steps are taken:
IOW:
var start = 0;
var deleteCount = 2;
var item1 = undefined;
// …
| 1. Let O be the result of calling ToObject passing the this value as the
| argument.
var O = [,, 0];
| 2. Let A be a new array created as if by the expression new Array() where
| Array is the standard built-in constructor with that name.
var A = [];
| 3. Let lenVal be the result of calling the [[Get]] internal method of O
| with argument "length".
var lenVal = O.length;
(lenVal === 3)
| 4. Let len be ToUint32(lenVal).
var len = 3 >>> 0;
(len === 3)
| 5. Let relativeStart be ToInteger(start).
function sign (x)
{
return (x < 0) ? -1 : 1;
}
function ToInteger (x)
{
return sign(x) * Math.floor(Math.abs(x));
}
var relativeStart = ToInteger(start);
(relativeStart === 0)
| 6. If relativeStart is negative, let actualStart be max((len +
| relativeStart),0); else let actualStart be min(relativeStart, len).
var actualStart = (relativeStart < 0)
? Math.max((len + relativeStart), 0);
: Math.min(relativeStart, len);
(actualStart === 0)
| 7. Let actualDeleteCount be min(max(ToInteger(deleteCount),0),
| len – actualStart).
var actualDeleteCount = Math.min(
Math.max(ToInteger(deleteCount), 0)),
len - actualStart);
(actualDeleteCount === 2)
| 8. Let k be 0.
var k = 0;
| 9. Repeat, while k < actualDeleteCount
while (k < actualDeleteCount)
{
| a. Let from be ToString(actualStart+k).
var from = String(actualStart + k);
| b. Let fromPresent be the result of calling the [[HasProperty]]
| internal method of O with argument from.
var fromPresent = from in O;
This is the step in the algorithm where apparently both Crockford and V8 are
wrong, according to the 5.1 Edition and earlier Editions. Crockford does
not consider `undefined' values for elements, and V8 does not consider
uninitialized elements (here: those with indexes 0 and 1).
| c. If fromPresent is true, then
if (fromPresent)
{
| i. Let fromValue be the result of calling the [[Get]] internal
| method of O with argument from.
var fromValue = O[from];
| ii. Call the [[DefineOwnProperty]] internal method of A with
| arguments ToString(k), Property Descriptor {[[Value]]:
| fromValue, [[Writable]]: true, [[Enumerable]]: true,
| [[Configurable]]: true}, and false.
A[String(k)] = fromValue;
}
| d. Increment k by 1.
++k;
}
| …
| 17. Return A.
return A;
| […]
> Which one is the correct implementation?
Neither one, according to the 5.1 Edition and earlier Editions that
specified this method.
___
[1] <http://PointedEars.de/es-matrix>
--
PointedEars
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Array.splice implementation in 'JS: The Good Parts' Jun Woong <woong@icu.ac.kr> - 2012-06-06 21:17 -0700
Array.prototype.splice implementation in 'JS: The Good Parts' (was: Array.splice implementation in 'JS: The Good Parts') Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-07 20:17 +0200
Re: Array.prototype.splice implementation in 'JS: The Good Parts' (was: Array.splice implementation in 'JS: The Good Parts') Jun Woong <woong@icu.ac.kr> - 2012-06-07 18:41 -0700
Re: Array.prototype.splice implementation in 'JS: The Good Parts' Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-06-08 09:48 +0200
csiph-web