archives

« Bugzilla Issues Index

#383 — Array.from (15.4.3.3) additional note describes Array.of


Currently, the NOTE reads


NOTE The from function is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or herited by any other constructors that may be called with a single numeric argument.


It should be updated to:



NOTE The from function is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single arrayLike argument.



The difference is in the type of argument (single numeric => arrayLike) it should accept and a minor typo fix.


No, numeric is actually correct. If this method is going to be invoked as a method of a constructor named Collection, eg:

let c = Collection.of(1,2,3)

then the dependency is upon being able to say:

new Collection(3) /* allocate a Collection with 3 elements */

That is because the semantics is roughly:

function of(...items) {
let result = new this(items.length);
for (i=0; i<item.length; ++i) result[i]=items[i];
return result;
}

I did fix the type...


I'm not disputing that for Array.of, I'm pointing out that it says the same thing under Array.from


It applies to both of them. The only real difference is that |of| works with a rest parameter while |from| works with a caller supplied array-like object. But they are both processed in exactly the same way.

They both do the equivalent of
new this(len)

The NOTE is referring to the fact that the this value (the constructor that |from| or |of| is invoked on needs to support a |new| call like above.


I've read through both of them, and I wrote the original document that David Herman linked to in the strawman proposal, I dont understand why there is a note referring to a call like this:

Array.from( 1 )

What would this produce?


(In reply to comment #4)
> I've read through both of them, and I wrote the original document that David
> Herman linked to in the strawman proposal, I dont understand why there is a
> note referring to a call like this:
>
> Array.from( 1 )

that's not what the note is referring to it is referring to a call like:
new Array(0)
which the function makes internally in step 7.a
>
> What would this produce?

An empty Array, essentially the same as:

Array.from([])

Array.from takes one argument. Step 1 coerces the argument to an object by calling ToObject. ToObject(1) produces a Number wrapper objects. Step 3 accesses the value of the wrapper objects "length" property. It doesn't have one so, lenValue is undefined. ToInteger(undefined) returns 0, so len is 0 after step 4. Step 7.a performs essentially new Array(len) and produces a length array. Step 11 does nothing because len is 0. Step 12 (redundantly in this case) updates the length of the array to 0 and finally step 14 returns the 0-length array as the value of Array.from.

This is all normal procedure for processing "array-like" objects in the built-ins. Because ToInteger(undefined) always yields 0 any object is effectively a 0-length array-like object.

For example:
[].forEach.call(1, function() {console.log('called')});

output nothing because 1 is converted into an array-like object of length 0.


Thanks - I understand the steps in the specification, but it's clear now that I misunderstood the "NOTE: ..." section, where it said "may be called with a single numeric argument."

Sorry for the noise