Why can't I access a property of an integer with a single dot?
The period is part of the number, so the code will be interpreted the same as:
(3.)toFixed(5)
This will naturally give a syntax error, as you can't immediately follow the number with an identifier.
Any method that keeps the period from being interpreted as part of the number would work. I think that the clearest way is to put parentheses around the number:
(3).toFixed(5)
Using integer keys with dot notation to access property in javascript objects
In case of dot notation to access a value, the property key must be a valid identifier
In this code, property must be a valid JavaScript identifier, i.e. a
sequence of alphanumerical characters, also including the underscore
("_") and dollar sign ("$"), that cannot start with a number. For
example, object.$1 is valid, while object.1 is not.
You can use bracket notation in this case
obj['1']
Spec: Property Accessors
Access numeric properties of an object using dot notation
Your question seems to be about why we can’t access array and array-like elements using the dot notation like this:
const v = a.0;
It’s described in the ECMAScript specification:
The dot notation is explained by the following syntactic conversion:
MemberExpression
.
IdentifierName
And identifiers may not start with a digit as described here:
- IdentifierName ::
- IdentifierStart
IdentifierName IdentifierPart
- IdentifierStart ::
- UnicodeLetter
$
_
\
UnicodeEscapeSequence
As for the reasoning, having identifier names just being made of digits would have made it difficult to write number literals. An exception could probably have been designed just for array access but that would have made the language more complex and departing from the common C family syntax without any real gain.
Can't access object property, even though it shows up in a console log
The output of console.log(anObject)
is misleading; the state of the object displayed is only resolved when you expand the Object tree displayed in the console, by clicking on >
. It is not the state of the object when you console.log
'd the object.
Instead, try console.log(Object.keys(config))
, or even console.log(JSON.stringify(config))
and you will see the keys, or the state of the object at the time you called console.log
.
You will (usually) find the keys are being added after your console.log
call.
Why don't number literals have access to Number methods?
You can access it the same way, it's a different parsing issue here, to do it, use a slightly different syntax:
(1).toString()
Numbers can have decimals, so the syntax for ending in a decimal is a bit ambiguous when you go to parse the code, use parenthesis to be valid. It's a bit clearer when you see that this is also valid:
(1.).toString()
However with just 1.toString()
it's trying to parse as a number with a decimal, and it fails.
Access to the number as an object
You need another dot to distinguish the first decimal separator from a dot as a property accessor.
console.log(2..constructor);
Why can't I dot-reference a hashtable key's value property if the property name is an integer
Note: This answer originally incorrectly claimed that $table.6
doesn't work, due to the hashtable key being integer-typed, but it works just fine, because the 6
in the .6
"property" access is parsed as an integer as well.
As Gyula Kokas' helpful answer points out, you're seeing problematic behavior in PowerShell's parser, present as of PowerShell 7.2, discussed in detail in GitHub issue #14036. The behavior is unrelated to hashtables per se:
What follows
.
, the member-access operator, is parsed as a number if it looks like a number literal, such as6
,6l
(a[long]
) or even6.0
(!, a[double]
).- See below for how that number is then used.
Any attempt to use another property access then triggers the error you saw:
$foo.6.bar # !! Error "Missing property name after reference operator."
In fact, following a property name that starts with a digit with a letter causes the error too - even though
6a
can not interpreted as a number literal.$foo.6a # !! Same error.
As an aside: PowerShell even allows you to use variable references, and even expressions (enclosed in (...)
) as property names (e.g., $propName = 'Length'; 'foo'.$propName
or ('foo'.('L' + 'ength')
Workarounds:
As you've demonstrated, enclosing the first property access in
(...)
-($table.6).Count
works, and so does$table.(6).Count
You've also demonstrated
$table[6].Count
, which works for hashtables.For accessing an object's actual property,
$obj.'6'.Count
would work too (given that property names are always strings), as it would with hashtables with string keys (e.g.@{ '6'= 'six' }.'6'.Length
)
Considerations specific to hashtables:
As a syntactic convenience, PowerShell allows property-access syntax ($obj.someProperty
) to also be used to access the entries of a hashtable, in which case the property "name" is taken as the key of an entry in the hashtable.
The type-native syntax to access hashtable entries is index syntax ($hash[$someKey]
).
While property names (referring to members of a .NET type) are invariably strings:
- a hashtable's keys can be of any type.
- on accessing an entry, the lookup key must not only have the right value, but must also be of the exact same type as the key stored in the hashtable.
Perhaps surprisingly, when defining a hashtable, unquoted keys situationally become either strings or numbers:
If the unquoted word can be interpreted as a number literal (e.g.,
6
), it is parsed as such, and you end up with a numeric key; in the case of6
, it will be[int]
-typed key, because the usual number-literal typing applies (e.g.,1.0
would become a[double]
key (not advisable, because binary floating-point values do not always have exact decimal representations), and2147483648
would become a[long]
).Otherwise (e.g.,
NameServers
), the key is[string]
-typed.- Caveat: If the name starts with a digit (but isn't a number literal; e.g.
6a
), an error occurs; use quoting ('6a'
) as a workaround - see GitHub issue #15925
- Caveat: If the name starts with a digit (but isn't a number literal; e.g.
That is, even though strings in expressions normally require quoting, for convenience you may omit the quoting when defining keys in hashtable literals - but the rules for recognizing number literals still apply.
Explicitly typing hashtable keys:
To ensure that a given key is interpreted as a
[string]
, quote it (e.g.,'6'
)Generally, you may also use a cast to type your keys explicitly. (e.g.
[long] 6
) or, in number literals, the usual number-type suffix characters, such asL
for[long]
(e.g.6L
) - see this answer for an overview of the supported suffixes, whose number has grown significantly in PowerShell (Core) 7+.
An example, based on your hashtable:
It follows from the above that your 6
key is of type [int]
(and would have to be defined as '6'
in your hashtable literal if you wanted it to be a string).
Because the 6
in $name.6
is also parsed as an [int]
, the lookup succeeds, but note that it wouldn't succeed if different numeric types were at play:
# !! Output is $null, because the entry key is of type [long],
# !! whereas the lookup key is [int].
@{ 6L = '[long] 6' }.6
Considerations specific to property access:
With actual property access (accessing a native member of a .NET type), the fact that names that look like numbers are actually parsed as numbers first - before, of necessity, being converted to strings - can result in surprising behavior:
# !! Output is $null, because the 6L after "." is parsed as a
# !! ([long]) number first, and then converted to a string, which
# !! results in "6" being used.
([pscustomobject] @{ '6L' = 'foo' }).6L
# OK - The quoting forces 6L to be a string.
([pscustomobject] @{ '6L' = 'foo' }).'6L' # -> 'foo'
Related Topics
Jquery Live Scroll Event on Mobile (Work Around)
How to Build & Deploy a Samsung Smarttv App Without the Ide (E.G: on Linux)
How to Set a Cookie for Another Domain
Shell Tool Which Renders Web Site Including JavaScript
Cross-Browser JavaScript Xml Parsing
Jquery in Greasemonkey 1.0 Conflicts with Websites Using Jquery
Jqgrid Server Side Error Message/Validation Handling
Es6 Class Variable Alternatives
How to Have a Default Option in Angular.Js Select Box
Why Don't Logical Operators (&& and ||) Always Return a Boolean Result
Is It Spread "Syntax" or the Spread "Operator"
Using Jquery to Test If an Input Has Focus
Difference Between Innertext, Innerhtml and Value
Pad a Number With Leading Zeros in JavaScript
How to Check If a Variable Is an Array in JavaScript
Uncaught Referenceerror: Function Is Not Defined with Onclick