Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Array.prototype.concat is not generic

DZone's Guide to

Array.prototype.concat is not generic

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

The ECMAScript 5.1 specification states that the array method concat is generic [1]. This post argues that that isn’t true in practice.

§15.4.4.4 of the ECMAScript 5.1 specification states:

The concat function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.
The code in this post uses [] as a shortcut for Array.prototype. That is a common technique, but it is slightly dirty: You access the methods of Array.prototype via an instance. However, this access is very fast in modern JavaScript engines, I suspect that some of them don’t even create an array instance, any more. All of the examples have been tried on Firefox and V8.

Let’s check the assertion that concat is generic: Its result must be the same regardless of whether this is a real array or just array-like (with a property length and indexed access to elements). We first try concat with an array as this:

    > ["hello"].concat(["world"])
    ["hello", "world"]

    > [].concat.call(["hello"], ["world"]) // same as above
    ["hello", "world"]
Next, we do the above concatenation with an array-like object. The result should be the same.
    > [].concat.call({ 0: "hello", length: 1 }, ["world"])
    [ { '0': 'hello', length: 1 }, 'world' ]
The special variable arguments is also array-like. The result is again not what we would expect from a generic method:
    > function f() { return [].concat.call(arguments, ["world"]) }
    > f("hello")
    [ { '0': 'hello' }, 'world' ]
To see a truly generic method in action, you just need to look at push:
    > var arrayLike = { 0: "hello", length: 1 };
    > [].push.call(arrayLike, "world")
    2
    > arrayLike
    { '0': 'hello', '1': 'world', length: 2 }
Reference:
  1. Uncurrying `this` in JavaScript” [explains what generic methods are]

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:

Published at DZone with permission of Axel Rauschmayer, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}