[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

array-like objects

ram

1/1/2016 6:12:00 PM

I define an object as follows (one line of input, one line
of output from the firefox console):

a = { length: 3 }
Object { length: 3 }

Now I observe the following three evaluations:

a[ 0 ]
undefined

a[ 1 ]
undefined

a[ 2 ]
undefined

. So, is »a« now an »array-like object«, because it has
a lenght between 0 and 9007199254740991 and it has three
entries for the numeric keys 0 <= key < lenght, which
just so happen to be »undefined«?

b = Array.from( a )
Array [ undefined, undefined, undefined ]

So, the only thing we require for an object to be »array-like«
is a length property with an appropriate value?

(The relevant section of ECMAScript seems to be
7.3.17 CreateListFromArrayLike (obj [, elementTypes] ).
I am asking here just to be sure. For example, I am not
sure whether an undefined value triggers an »ReturnIfAbrupt«,
but it does not seem to be so.)

39 Answers

Aleksandro

1/1/2016 6:34:00 PM

0

On 01/01/16 15:11, Stefan Ram wrote:
> So, the only thing we require for an object to be »array-like«
> is a length property with an appropriate value?

Sounds reasonable as Javascript is considered a duck typed language.
https://en.wikipedia.org/wiki/D...

Thomas 'PointedEars' Lahn

1/2/2016 12:31:00 AM

0

Aleksandro wrote:
^^^^^^^^^^
Your last name belongs there as well.

> On 01/01/16 15:11, Stefan Ram wrote:
>> So, the only thing we require for an object to be »array-like«
>> is a length property with an appropriate value?
>
> Sounds reasonable as Javascript is considered a duck typed language.
> https://en.wikipedia.org/wiki/D...

There is no â??Javascriptâ?.

_ECMAScript implementations_ are _not_ â??duck typed language[s]â?; instead,
most of them support dynamic type-checking (often misnamed â??loose typingâ?).

â??Duck typingâ? is a programming technique instead that can be used with
programming languages that support dynamic type-checking, but also with
other programming languages.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.0

Aleksandro

1/2/2016 1:19:00 AM

0

On 01/01/16 21:30, Thomas 'PointedEars' Lahn wrote:
> Aleksandro wrote:
> ^^^^^^^^^^
> Your last name belongs there as well.
>
>> On 01/01/16 15:11, Stefan Ram wrote:
>>> So, the only thing we require for an object to be »array-like«
>>> is a length property with an appropriate value?
>>
>> Sounds reasonable as Javascript is considered a duck typed language.
>> https://en.wikipedia.org/wiki/D...
>
> There is no â??Javascriptâ?.

Just for the record, what group are we in?

> _ECMAScript implementations_ are _not_ â??duck typed language[s]â?; instead,
> most of them support dynamic type-checking (often misnamed â??loose typingâ?).
>
> â??Duck typingâ? is a programming technique instead that can be used with
> programming languages that support dynamic type-checking, but also with
> other programming languages.

Tim Streater

1/2/2016 8:29:00 AM

0

In article <n678dd$9a0$1@dont-email.me>, Aleksandro
<aleksandro@gmx.com> wrote:

>On 01/01/16 21:30, Thomas 'PointedEars' Lahn wrote:
>> Aleksandro wrote:
>> ^^^^^^^^^^
>> Your last name belongs there as well.
>>
>>> On 01/01/16 15:11, Stefan Ram wrote:
>>>> So, the only thing we require for an object to be »array-like«
>>>> is a length property with an appropriate value?
>>>
>>> Sounds reasonable as Javascript is considered a duck typed language.
>>> https://en.wikipedia.org/wiki/D...
>>
>> There is no â??Javascriptâ?.
>
>Just for the record, what group are we in?

We're in the javascript group. PointyHead is just being an arsehole as
usual.

--
"If you're not able to ask questions and deal with the answers without feeling
that someone has called your intelligence or competence into question, don't
ask questions on Usenet where the answers won't be carefully tailored to avoid
tripping your hair-trigger insecurities." - D M Procida, UCSM

Thomas 'PointedEars' Lahn

1/2/2016 9:46:00 AM

0

Aleksandro wrote:
^^^^^^^^^^
Which part of â??last nameâ? did you not understand?

> On 01/01/16 21:30, Thomas 'PointedEars' Lahn wrote:
>> Aleksandro wrote:
>> ^^^^^^^^^^
>> Your last name belongs there as well.
>>
>>> On 01/01/16 15:11, Stefan Ram wrote:
>>>> So, the only thing we require for an object to be »array-like«
>>>> is a length property with an appropriate value?
>>>
>>> Sounds reasonable as Javascript is considered a duck typed language.
>>> https://en.wikipedia.org/wiki/D...
>>
>> There is no â??Javascriptâ?.
>
> Just for the record, what group are we in?

comp.lang.javascript. That does not mean anything, if you cared to read.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

JR

1/2/2016 3:27:00 PM

0

On 01/01/2016 04:11 PM, Stefan Ram wrote:
> I define an object as follows (one line of input, one line
> of output from the firefox console):
>
> a = { length: 3 }
> Object { length: 3 }

You have declared the "a" variable using the Object literal notation,
containing just one key/value pair: length / 3. So, a is an object
inheriting the Object prototype. Seemingly, the same could have been
achieved with:

var a = {};
a.length = 3;

However, to see the real length of the object, you need to write:

Object.keys(a).length // logs 1

>
> Now I observe the following three evaluations:
>
> a[ 0 ]
> undefined
>
> a[ 1 ]
> undefined
>
> a[ 2 ]
> undefined

As noted above, "a" is an object, not an array. That's why you are
getting undefined whenever you try to access non existent properties of
the object. Try a['whatever'] for instance.

>
> . So, is »a« now an »array-like object«, because it has
> a lenght between 0 and 9007199254740991 and it has three
> entries for the numeric keys 0 <= key < lenght, which
> just so happen to be »undefined«?
>
> b = Array.from( a )
> Array [ undefined, undefined, undefined ]

Array.from() is supposed to be used with array-like or iterable objects
such as Map and Set. So you cannot pass non iterable objects such as
your "a".

When you write Array.from(a), I think JavaScript is creating an
array-like object with the length of 3 under the hood, so that the code
produces:

[ undefined, undefined, undefined ]

But I need to confirm that behaviour in the ECMA2015 Specification to be
sure.

>
> So, the only thing we require for an object to be »array-like«
> is a length property with an appropriate value?

No, array-like objects must have:
- indexed access to elements and the property length that tells us how
many elements the object has.
- do not have array methods such as push(), forEach() and indexOf().

See:
<http://www.2ality.com/2013/05/quirk-array-like-object...



--
Joao Rodrigues

Thomas 'PointedEars' Lahn

1/2/2016 7:48:00 PM

0

Joao Rodrigues wrote:

> On 01/01/2016 04:11 PM, Stefan Ram wrote:
>> I define an object as follows (one line of input, one line
>> of output from the firefox console):
>>
>> a = { length: 3 }
>> Object { length: 3 }
>
> You have declared the "a" variable using the Object literal notation,

No, as far as we know, he has _not_ declared a variable. Because that would
require â??var aâ? or â??var â?¦, aâ? or â??var â?¦, a, â?¦â?. You have been told this
before. Most recently, only three days ago.

> containing just one key/value pair: length / 3. So, a is an object
> inheriting the Object prototype.

No, the value of â??aâ? (likely â??aâ? is a user-defined property of the global
object then) is a reference to an object inheriting from the object
initially referred to by the value of (the property) â??Object.prototypeâ?.

> Seemingly, the same could have been achieved with:
>
> var a = {};
> a.length = 3;

Not only seemingly.

> However, to see the real length of the object, you need to write:
>
> Object.keys(a).length // logs 1

Nonsense. You are missing the point.

>> Now I observe the following three evaluations:
>>
>> a[ 0 ]
>> undefined
>>
>> a[ 1 ]
>> undefined
>>
>> a[ 2 ]
>> undefined
>
> As noted above, "a" is an object, not an array.

â??aâ? is not an object, it is an identifier. It might also be the name of a
property.

> That's why you are getting undefined whenever you try to access non
> existent properties of the object.

This has nothing to do with the fact that (the value of) â??aâ? does not refer
to an Array instance. The question was explicitly about array-*like*
objects.

> Try a['whatever'] for instance.

Or â??a.whateverâ?, since â??whateverâ? is not (going to be) a reserved word.

>> b = Array.from( a )
>> Array [ undefined, undefined, undefined ]
>
> Array.from() is supposed to be used with array-like or iterable objects
> such as Map and Set. So you cannot pass non iterable objects such as
> your "a".

Nonsense. Array.from() is explicitly designed to make use of references to
such objects, to convert them them into real Array instances.

> When you write Array.from(a), I think JavaScript is creating an
> array-like object with the length of 3 under the hood,

No, â??JavaScriptâ? does not do anything of the sort. Instead, a conforming
implementation of ECMAScript 2015, such as Google V8 JavaScript, creates an
*Array* instance with the length 3. Because *that* is the purpose of
*Array*.from().

> so that the code produces:
>
> [ undefined, undefined, undefined ]

That would not be an array-*like* object, now would it? And it is not; it
is an Array instance; the value of the internal â??[[Class]]â? property is
*obvious* from the posted console outputâ?¦

> But I need to confirm that behaviour in the ECMA2015 Specification to be
> sure.

Why do you *still* not check your assumptions *before* you post? Nobody
needs your many misconceptions, and to waste their free time correcting
them.

<http://www.ecma-international.org/ecma-262/6.0/#sec-arra...

>> So, the only thing we require for an object to be »array-like«
>> is a length property with an appropriate value?
>
> No, array-like objects must have:
> - indexed access to elements and the property length that tells us how
> many elements the object has.
> - do not have array methods such as push(), forEach() and indexOf().

Nonsense.

> See:
> <http://www.2ality.com/2013/05/quirk-array-like-object...

You should stop believing blindly everything that you read or hear.

Barring a *standard* definition, an array-like object is one that behaves
like an array at least on property read access. Nothing more, nothing less.
For an object in an ECMAScript implementation that means that it has
indexes â?? properties whose names are unsigned integers â?? and that it has a
â??lengthâ? property whose value indicates the greatest next usable index.

However, fortunately, the term â??array-likeâ? is used in ECMAScript 2015
several times, from which one can derive the definition I gave above:

| 6.2.1 The List and Record Specification Type
|
| [â?¦]
| For notational convenience an array-like syntax can be used to access List
| elements. For example, arguments[2] is shorthand for saying the 3rd
| element of the List arguments.

| 6.2.6 Data Blocks
|
| [â?¦]
| For notational convenience within this specification, an array-like syntax
| can be used to access the individual bytes of a Data Block value. This
| notation presents a Data Block value as a 0-origined integer indexed
| sequence of bytes. For example, if db is a 5 byte Data Block value then $
| db[2] can be used to access its 3rd byte.

| 7.1.15 ToLength ( argument )
|
| The abstract operation ToLength converts argument to an integer suitable
| for use as the length of an array-like object. [â?¦]

| 7.3.17 CreateListFromArrayLike (obj [, elementTypes] )
|
| The abstract operation CreateListFromArrayLike is used to create a List
| value whose elements are provided by the indexed properties of an array-
| like object, obj. [â?¦]

| 22.1.2.1 Array.from ( items [ , mapfn [ , thisArg ] ] )
|
| [â?¦]
| 7. Assert: items is not an Iterable so assume it is an array-like object.
| [â?¦]

| 22.2 TypedArray Objects
|
| TypedArray objects present an array-like view of an underlying binary data
| buffer (24.1). [â?¦]

| 22.2.2.1.1 Runtime Semantics: TypedArrayFrom( constructor, items, mapfn,
| thisArg )
|
| [â?¦]
| 9. Assert: items is not an Iterable so assume it is an array-like object.
| [â?¦]

| 23.1.1.1 Map ( [ iterable ] )
|
| NOTE
| If the parameter iterable is present, it is expected to be an object that
| implements an @@iterator method that returns an iterator object that
| produces a two element array-like object whose first element is a value
| that will be used as a Map key and whose second element is the value to
| associate with that key.

| 23.3.1.1 WeakMap ( [ iterable ] )
|
| [â?¦]
| If the parameter iterable is present, it is expected to be an object that
| implements an @@iterator method that returns an iterator object that
| produces a two element array-like object whose first element is a value
| that will be used as a WeakMap key and whose second element is the value
| to associate with that key.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

JR

1/3/2016 12:26:00 PM

0

Joao Rodrigues escreveu:
> On 01/01/2016 04:11 PM, Stefan Ram wrote:
> > I define an object as follows (one line of input, one line
> > of output from the firefox console):
> >
> > a = { length: 3 }
> > Object { length: 3 }


> >
> > Now I observe the following three evaluations:
> >
> > a[ 0 ]
> > undefined
> >
> > a[ 1 ]
> > undefined
> >
> > a[ 2 ]
> > undefined
>
> As noted above, "a" is an object, not an array. That's why you are
> getting undefined whenever you try to access non existent properties of
> the object. Try a['whatever'] for instance.

Try a['length'] or a.length and you'll get 3, because there is such property in the object.


> > . So, is »a« now an »array-like object«, because it has
> > a lenght between 0 and 9007199254740991 and it has three
> > entries for the numeric keys 0 <= key < lenght, which
> > just so happen to be »undefined«?
> >
> > b = Array.from( a )
> > Array [ undefined, undefined, undefined ]
>
> Array.from() is supposed to be used with array-like or iterable objects
> such as Map and Set. So you cannot pass non iterable objects such as
> your "a".

In reality, Array.from() also accepts non iterable objects such as { length: 3 }, but the result can be tricky to understand, as Array.from() was designed to work with array-like or iterable objects

E.g. Array.from({g:50, t:20}) produces [].

>
> When you write Array.from(a), I think JavaScript is creating an
> array-like object with the length of 3 under the hood, so that the code
> produces:
>
> [ undefined, undefined, undefined ]
>
> But I need to confirm that behaviour in the ECMA2015 Specification to be
> sure.

I have confirmed that Array.from() is creating an array, following the steps of the ES6 Specification, section 22.1.2.1:
<http://ecma-international.org/ecma-262/6.0/index.html#sec-arra...

Let's recap the example:

var a = { length: 3 }
Array.from(a) // [undefined, undefined, undefined]

Now, let's comment on the relevant steps of the Array.from()

22.1.2.1 - Array.from ( items [ , mapfn [ , thisArg ] ] )
[...]
Step 10 - Let len be ToLength(Get(arrayLike, "length")).

The abstract operation Get is used to retrieve the value of a specific property (P) of an object (O), as specified in section 7.3.1. So Get(O,P) will be Get(a,"length"), and we know that a.length returns 3.

let len = toLength(a.length); // 3

Step 13 - Let A be ArrayCreate(len). The abstract operation ArrayCreate is defined in section 9.4.2.2.

let A = new Array(len);

Step 15 - Let k be 0.
Step 16 - Repeat, while k < len. And following steps a thru h, we have something like:

while (k < len) {
v = items[k]; // v = a[k], so v = undefined.
if (mapFn) {
//
} else {
A[k] = v; // A[k] = undefined.
}
k = k + 1;
}

Step 17 - Let setStatus be Set(A, "length", len, true).

Step 19 - Return A.

So, after all these steps, Array.from(a) will return the array
[undefined, undefined, undefined].

But if you write:

var a = { length: 3 }
Array.from(a, (value, key) => key);

FF and Chrome console will print out [0, 1, 2], instead of [undefined, undefined, undefined]


> > So, the only thing we require for an object to be »array-like«
> > is a length property with an appropriate value?
>
> No, array-like objects must have:
> - indexed access to elements and the property length that tells us how
> many elements the object has.
> - do not have array methods such as push(), forEach() and indexOf().
>
> See:
> <http://www.2ality.com/2013/05/quirk-array-like-object...
>

For short, "array-like" objects have a length property and indexed elements.

--
Joao Rodrigues

John Harris

1/3/2016 3:50:00 PM

0

On Sat, 02 Jan 2016 20:48:26 +0100, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:

>Joao Rodrigues wrote:

<snip>
>> As noted above, "a" is an object, not an array.
>
>?a? is not an object, it is an identifier.
<snip>

There is something wrong with this assertion. Suppose someone says
"Please talk to Thomas."
Do you expect to hear
"That's nonsense! Thomas is a name, not something you can talk to."
(To be incredibly precise, Thomas is not even a name; it's a computer
representation of a name).

Equally, when the compiler sees
a = 5;
does it say
"Nonsense; 'a' is an identifier. You can't change it."

John

Thomas 'PointedEars' Lahn

1/3/2016 3:54:00 PM

0

Joao Rodrigues wrote:

> Joao Rodrigues escreveu:
>> Array.from() is supposed to be used with array-like or iterable objects
>> such as Map and Set. So you cannot pass non iterable objects such as
>> your "a".
> In reality, Array.from() also accepts non iterable objects such as {
> length: 3 }, but the result can be tricky to understand, as Array.from()
> was designed to work with array-like or iterable objects
>
> E.g. Array.from({g:50, t:20}) produces [].

What is â??tricky to understandâ? about this? The object does not have a (non-
undefined) length property, so the length of the resulting array must be 0.

>> When you write Array.from(a), I think JavaScript is creating an
>> array-like object with the length of 3 under the hood, so that the code
>> produces:
>>
>> [ undefined, undefined, undefined ]
>>
>> But I need to confirm that behaviour in the ECMA2015 Specification to be
>> sure.
>
> I have confirmed

â?¦ after I corrected you the day before â?¦

> that Array.from() is creating an array

IOW, you have confirmed that you were wrong. An Array instance is not an
â??array-like objectâ? in the sense that you used the term.

> So, after all these steps, Array.from(a) will return the array
> [undefined, undefined, undefined].

You donâ??t sayâ?¦

/* [object Array] */
({}).toString.call(Array.from({length: 3}))

As can be seen in the Firefox console output *in the OP*.

> But if you write:
>
> var a = { length: 3 }
> Array.from(a, (value, key) => key);
>
> FF and Chrome console will print out [0, 1, 2], instead of [undefined,
> undefined, undefined]

Not surprising since you are mapping the â??undefinedâ?s of the property
accesses â?¦[0], â?¦[1], and â?¦[2] to their indexes 1, 2, and 3. The above
can also be written

Array.from(a, function (value, key) { return key; });

Incidentally, JSX has provided jsx.array.from() (for array-like objects) and
jsx.array.fromObject() (for iterables) for several years before ECMAScript
2015.

<http://PointedEars.de/wsvn/JSX?op=comp&a...[]=/trunk/object.js@392&compare[]=/trunk/object.js@393>
<http://PointedEars.de/wsvn/JSX?op=comp&a...[]=/trunk/@568&compare[]=/trunk/@569>

>> > So, the only thing we require for an object to be »array-like«
>> > is a length property with an appropriate value?
>> No, array-like objects must have:
>> - indexed access to elements and the property length that tells us how
>> many elements the object has.
>> - do not have array methods such as push(), forEach() and indexOf().
>>
>> See:
>> <http://www.2ality.com/2013/05/quirk-array-like-object...
>
> For short, "array-like" objects have a length property and indexed
> elements.

You donâ??t sayâ?¦

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.