When declaring an object literal, are keys evaluated in order? [duplicate] - javascript

Say I have an object which assigns properties based off the return value of a function:
var i = 0;
var f = function() { return ++i; }
var foo = {
a:f(),
b:f(),
c:f()
};
Is it guaranteed that foo.a will be 1, foo.b will be 2, and foo.c will be 3? I know that JS doesn't guarantee order when you iterate over an object, what about assignment?
Is it specified in the JS specification somewhere? I'm only asking for educational reasons.
Thanks.

Standard ECMA-262 (5.1) - Section 11.1.5 - Object Initialiser
The production PropertyNameAndValueList : PropertyNameAndValueList ,
PropertyAssignment is evaluated as follows:
1. Let obj be the result of evaluating PropertyNameAndValueList.
2. Let propId be the result of evaluating PropertyAssignment.
...
5. Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
6. Return obj.
So yes, the order is enforced by the standard.

From the ECMAScript 6 wiki, which will define the new version of JS:
When a scope (Block, FunctionBody, Program, ModuleBody, etc.) is entered, the variables declared by all immediately contained function and class declarations are bound to their respective functions and classes. Then all class bodies are executed in textual order. A class body defines and initializes class-wide properties once when the class definition is evaluated. This includes properties on the constructor function (the “class” itself) and on its prototype property. These initializations happen in textual order.
Your source has arrived! JavaScript object properties are initialized in textual order on objects. Arrays do not (currently) always follow this rule.
Source: http://wiki.ecmascript.org/doku.php?id=harmony:classes
I will edit this post when I find the reference in ECMAScript 5, though I am certain it is there.
Edit: Found it
ECMAScript 5 does have it: http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.7 .
If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used to order the list elements in step 3 of this algorithm.
This defines the calls to DefineOwnProperty and therefore the position of the properties in the internal table.

Assignment is always in order. It is just the way the code is found, interpreted and executed.

Yes, you are guaranteed that a will be 1, b will be 2, etc. Each f() will be interpreted in the order you wrote them.

I don't have an official source to quote, but let's just use a little common sense.
What if assignment wasn't done in order? You could never know which value would be assigned to which property, making the object structure useless (at least when using the object literal syntax).
It makes no difference if it's a function call, or a primitive literal, or some other value. If it wasn't guaranteed to happen in order, it just wouldn't work.
After doing a quick search of the term left to right in ECMAScript 5, here are some results if it helps you:
7 Lexical Conventions
The source text of an ECMAScript program is first converted into a sequence of input elements, which are tokens, line terminators, comments, or white space. The source text is scanned from left to right, repeatedly taking the longest possible sequence of characters as the next input element.
11.8.5 The Abstract Relational Comparison Algorithm
...It is necessary because ECMAScript specifies left to right evaluation of expressions.
Annex D (informative) Corrections and Clarifications in the 5th Edition with Possible 3rd Edition Compatibility Impact
ECMAScript generally uses a left to right evaluation order, however the Edition 3 specification language for the > and <= operators resulted in a partial right to left order. The specification has been corrected for these operators such that it now specifies a full left to right evaluation order.

Related

Is order guaranteed for initializing Javascript objects? [duplicate]

Say I have an object which assigns properties based off the return value of a function:
var i = 0;
var f = function() { return ++i; }
var foo = {
a:f(),
b:f(),
c:f()
};
Is it guaranteed that foo.a will be 1, foo.b will be 2, and foo.c will be 3? I know that JS doesn't guarantee order when you iterate over an object, what about assignment?
Is it specified in the JS specification somewhere? I'm only asking for educational reasons.
Thanks.
Standard ECMA-262 (5.1) - Section 11.1.5 - Object Initialiser
The production PropertyNameAndValueList : PropertyNameAndValueList ,
PropertyAssignment is evaluated as follows:
1. Let obj be the result of evaluating PropertyNameAndValueList.
2. Let propId be the result of evaluating PropertyAssignment.
...
5. Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
6. Return obj.
So yes, the order is enforced by the standard.
From the ECMAScript 6 wiki, which will define the new version of JS:
When a scope (Block, FunctionBody, Program, ModuleBody, etc.) is entered, the variables declared by all immediately contained function and class declarations are bound to their respective functions and classes. Then all class bodies are executed in textual order. A class body defines and initializes class-wide properties once when the class definition is evaluated. This includes properties on the constructor function (the “class” itself) and on its prototype property. These initializations happen in textual order.
Your source has arrived! JavaScript object properties are initialized in textual order on objects. Arrays do not (currently) always follow this rule.
Source: http://wiki.ecmascript.org/doku.php?id=harmony:classes
I will edit this post when I find the reference in ECMAScript 5, though I am certain it is there.
Edit: Found it
ECMAScript 5 does have it: http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.7 .
If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used to order the list elements in step 3 of this algorithm.
This defines the calls to DefineOwnProperty and therefore the position of the properties in the internal table.
Assignment is always in order. It is just the way the code is found, interpreted and executed.
Yes, you are guaranteed that a will be 1, b will be 2, etc. Each f() will be interpreted in the order you wrote them.
I don't have an official source to quote, but let's just use a little common sense.
What if assignment wasn't done in order? You could never know which value would be assigned to which property, making the object structure useless (at least when using the object literal syntax).
It makes no difference if it's a function call, or a primitive literal, or some other value. If it wasn't guaranteed to happen in order, it just wouldn't work.
After doing a quick search of the term left to right in ECMAScript 5, here are some results if it helps you:
7 Lexical Conventions
The source text of an ECMAScript program is first converted into a sequence of input elements, which are tokens, line terminators, comments, or white space. The source text is scanned from left to right, repeatedly taking the longest possible sequence of characters as the next input element.
11.8.5 The Abstract Relational Comparison Algorithm
...It is necessary because ECMAScript specifies left to right evaluation of expressions.
Annex D (informative) Corrections and Clarifications in the 5th Edition with Possible 3rd Edition Compatibility Impact
ECMAScript generally uses a left to right evaluation order, however the Edition 3 specification language for the > and <= operators resulted in a partial right to left order. The specification has been corrected for these operators such that it now specifies a full left to right evaluation order.

ECMAScript code execution order [duplicate]

Say I have an object which assigns properties based off the return value of a function:
var i = 0;
var f = function() { return ++i; }
var foo = {
a:f(),
b:f(),
c:f()
};
Is it guaranteed that foo.a will be 1, foo.b will be 2, and foo.c will be 3? I know that JS doesn't guarantee order when you iterate over an object, what about assignment?
Is it specified in the JS specification somewhere? I'm only asking for educational reasons.
Thanks.
Standard ECMA-262 (5.1) - Section 11.1.5 - Object Initialiser
The production PropertyNameAndValueList : PropertyNameAndValueList ,
PropertyAssignment is evaluated as follows:
1. Let obj be the result of evaluating PropertyNameAndValueList.
2. Let propId be the result of evaluating PropertyAssignment.
...
5. Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
6. Return obj.
So yes, the order is enforced by the standard.
From the ECMAScript 6 wiki, which will define the new version of JS:
When a scope (Block, FunctionBody, Program, ModuleBody, etc.) is entered, the variables declared by all immediately contained function and class declarations are bound to their respective functions and classes. Then all class bodies are executed in textual order. A class body defines and initializes class-wide properties once when the class definition is evaluated. This includes properties on the constructor function (the “class” itself) and on its prototype property. These initializations happen in textual order.
Your source has arrived! JavaScript object properties are initialized in textual order on objects. Arrays do not (currently) always follow this rule.
Source: http://wiki.ecmascript.org/doku.php?id=harmony:classes
I will edit this post when I find the reference in ECMAScript 5, though I am certain it is there.
Edit: Found it
ECMAScript 5 does have it: http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.7 .
If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used to order the list elements in step 3 of this algorithm.
This defines the calls to DefineOwnProperty and therefore the position of the properties in the internal table.
Assignment is always in order. It is just the way the code is found, interpreted and executed.
Yes, you are guaranteed that a will be 1, b will be 2, etc. Each f() will be interpreted in the order you wrote them.
I don't have an official source to quote, but let's just use a little common sense.
What if assignment wasn't done in order? You could never know which value would be assigned to which property, making the object structure useless (at least when using the object literal syntax).
It makes no difference if it's a function call, or a primitive literal, or some other value. If it wasn't guaranteed to happen in order, it just wouldn't work.
After doing a quick search of the term left to right in ECMAScript 5, here are some results if it helps you:
7 Lexical Conventions
The source text of an ECMAScript program is first converted into a sequence of input elements, which are tokens, line terminators, comments, or white space. The source text is scanned from left to right, repeatedly taking the longest possible sequence of characters as the next input element.
11.8.5 The Abstract Relational Comparison Algorithm
...It is necessary because ECMAScript specifies left to right evaluation of expressions.
Annex D (informative) Corrections and Clarifications in the 5th Edition with Possible 3rd Edition Compatibility Impact
ECMAScript generally uses a left to right evaluation order, however the Edition 3 specification language for the > and <= operators resulted in a partial right to left order. The specification has been corrected for these operators such that it now specifies a full left to right evaluation order.

Javascript property key - function

In the following example:
var tester = Object.create(null);
tester.forename = "Bob";
tester[function () { return "surname"; }] = "Jones";
Is javascript simply converting the function definition to a string to use as the property key?
Is javascript simply converting the function definition to a string to use as the property key?
Yes. Note that the string will not be "surname". In fact, to date, it's not specified what the string will be, and it varies from engine to engine. On some engines, it will be roughly what you have in the source. But it would be perfectly valid (e.g., within the spec) for it to be "dunno, some function". The next spec, ES6, is likely to say that, for Function#toString:
An implementation-dependent String source code representation of the this object is returned. This
representation has the syntax of a FunctionDeclaration FunctionExpression, GeneratorDeclaration,
GeneratorExpession, ClassDeclaration, ClassExpression, ArrowFunction, MethodDefinition, or GeneratorMethod
depending upon the actual characteristics of the object. In particular that the use and placement of white space, line
terminators, and semicolons within the representation String is implementation-dependent.
(This is the January 2014 wording.)
But that's the next spec, which isn't final yet, and will probably change a bit as the spec approaches completion (particularly with regard to native functions). As of the current spec, Function#toString can return anything it likes, and it need not vary from function to function.
Yes. The property names of objects are always strings.
If you attempt to use a different type, it will be coerced into string.
If you want them to be other types, you can use ES6 Map.

Javascript: function arguments and arguments[]

I'm a Javascript novice so please excuse the fundamental question.
I'm working my way through 'Professional Javascript For Web Developers' and in Chapter 3, "Understanding Arguments" section, it discusses accessing function arguments with the arguments[] keyword.
One of the examples shows that you can modify the values in arguments[]:
function twoNums(num1, num2) {
arguments[1] = 10;
console.log(arguments[0] + num2);
}
twoNums(4,8); output = 14
But it goes on to say that "This effect goes only one way: changing the named argument does not result in a change to the corresponding value in arguments."
However, changing the code to:
function twoNums(num1, num2) {
num2 = 10;
console.log(arguments[0] + arguments[1]);
}
twoNums(4,8); output = 14
results in the same output so the value in 'arguments[1]' is definitely changing.
Is this:
an error in the book?
an error in my understanding?
something that has changed in Javascript since the writing of the book?
Thanks,
Neil
ANSWERED: A combination of answers solved my problem. Thanks everyone.
It is supposed to work that way, unless in strict mode:
function foo(a) {
"use strict";
console.log(a, arguments[0]);
a = 10;
console.log(a, arguments[0]);
arguments[0] = 20;
console.log(a, arguments[0]);
}
foo(1);
// output:
// 1 1
// 10 1
// 10 20
The ES5 specification addresses that on section 10.6:
NOTE 1 For non-strict mode functions the array index (defined in 15.4) named data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function’s execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object’s properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.
Maybe it worked differently on ES3 (the previous version), but I doubt it (since they had to add a special case for strict mode).
Interesting fact: the presence of an eval call in the function can influence how the arguments object behave in some browsers, which is extremely weird. The use of the non-standard functionName.arguments reference also has an impact. See Why does an unexecuted eval have an effect on behavior in some browsers?, and my answer to it.
There is an error in the book, by the looks of things: if you reassign any of the arguments passed, the arguments object will change (both reference the same value).
Perhaps, though, what was meant in the book was this:
function f(n1, n2)
{
arguments[0] = 2;
console.log(arguments[0] + arguments[1]);
}
f(1, 2);//logs 4
f(1234,2);//logs 4
But, honestly, it shouldn't really matter. The arguments object should be treated as a read-only object. It's a good idea to uphold the mantra "Don't change objects you don't own" in JS. It's a bad idea trying to change the Object.prototype, as it is not the best of ideas to change the behaviour of any object (console, window...) by deleting and adding methods at random.
If you want to get some more details on arguments, or anything else MDN is there to help. I've not looked at all code examples there, but AFAIKT there's no code that effectively changes the arguments object.
Some time ago I think I read an article my Douglas Crockford on the matter, where he gave an example of how changing the arguments object actually lead to unexpected behaviour (arguments swapping places and all that).
Edit:
I'd thought I'd not go into strict mode, but as bfavaretto's answer pointed out: strict-mode actually does make the arguments object a read-only object. That's terrific news, and now I have all the more reason to love the way JS is going. ES6 will introduce block scoping and probably make the arguments object read-only all the time (at least, I hope it will).
it will work that way only in strict mode..
"use strict"
The Arguments object has one very unusual feature. In non-strict mode,
when a function has named parameters, the array elements of the
Arguments object are aliases for the parameters that hold the function
arguments. The numbered elements of the Arguments object and the
parameter names are like two different names for the same variable.
Changing the value of an argument with an argument name changes the
value that is retrieved through the arguments[] array. Conversely,
changing the value of an argument through the arguments[] array
changes the value that is retrieved by the argument name. Here is an
example that clarifies this:
function f(x) {
console.log(x); // Displays the initial value of the argument
arguments[0] = null; // Changing the array element also changes x!
console.log(x); // Now displays "null" } This is emphatically not the behavior you would see if the Arguments object
were an ordinary array. In that case, arguments[0] and x could refer
initially to the same value, but a change to one would have no effect
on the other.
This special behavior of the Arguments object has been removed in the
strict mode of ECMAScript 5. There are other strict-mode differences
as well. In non-strict functions, arguments is just an identifier. In
strict mode, it is effectively a reserved word. Strict-mode functions
cannot use arguments as a parameter name or as a local variable name,
and they cannot assign values to arguments.
Here is a great (and recent) article on this topic:
https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-8/function-arguments-and
I Suggest you use it :)

Are Javascript Object Properties assigned in order?

Say I have an object which assigns properties based off the return value of a function:
var i = 0;
var f = function() { return ++i; }
var foo = {
a:f(),
b:f(),
c:f()
};
Is it guaranteed that foo.a will be 1, foo.b will be 2, and foo.c will be 3? I know that JS doesn't guarantee order when you iterate over an object, what about assignment?
Is it specified in the JS specification somewhere? I'm only asking for educational reasons.
Thanks.
Standard ECMA-262 (5.1) - Section 11.1.5 - Object Initialiser
The production PropertyNameAndValueList : PropertyNameAndValueList ,
PropertyAssignment is evaluated as follows:
1. Let obj be the result of evaluating PropertyNameAndValueList.
2. Let propId be the result of evaluating PropertyAssignment.
...
5. Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
6. Return obj.
So yes, the order is enforced by the standard.
From the ECMAScript 6 wiki, which will define the new version of JS:
When a scope (Block, FunctionBody, Program, ModuleBody, etc.) is entered, the variables declared by all immediately contained function and class declarations are bound to their respective functions and classes. Then all class bodies are executed in textual order. A class body defines and initializes class-wide properties once when the class definition is evaluated. This includes properties on the constructor function (the “class” itself) and on its prototype property. These initializations happen in textual order.
Your source has arrived! JavaScript object properties are initialized in textual order on objects. Arrays do not (currently) always follow this rule.
Source: http://wiki.ecmascript.org/doku.php?id=harmony:classes
I will edit this post when I find the reference in ECMAScript 5, though I am certain it is there.
Edit: Found it
ECMAScript 5 does have it: http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.3.7 .
If an implementation defines a specific order of enumeration for the for-in statement, that same enumeration order must be used to order the list elements in step 3 of this algorithm.
This defines the calls to DefineOwnProperty and therefore the position of the properties in the internal table.
Assignment is always in order. It is just the way the code is found, interpreted and executed.
Yes, you are guaranteed that a will be 1, b will be 2, etc. Each f() will be interpreted in the order you wrote them.
I don't have an official source to quote, but let's just use a little common sense.
What if assignment wasn't done in order? You could never know which value would be assigned to which property, making the object structure useless (at least when using the object literal syntax).
It makes no difference if it's a function call, or a primitive literal, or some other value. If it wasn't guaranteed to happen in order, it just wouldn't work.
After doing a quick search of the term left to right in ECMAScript 5, here are some results if it helps you:
7 Lexical Conventions
The source text of an ECMAScript program is first converted into a sequence of input elements, which are tokens, line terminators, comments, or white space. The source text is scanned from left to right, repeatedly taking the longest possible sequence of characters as the next input element.
11.8.5 The Abstract Relational Comparison Algorithm
...It is necessary because ECMAScript specifies left to right evaluation of expressions.
Annex D (informative) Corrections and Clarifications in the 5th Edition with Possible 3rd Edition Compatibility Impact
ECMAScript generally uses a left to right evaluation order, however the Edition 3 specification language for the > and <= operators resulted in a partial right to left order. The specification has been corrected for these operators such that it now specifies a full left to right evaluation order.

Categories

Resources