In the examples I've seen so far using Symbols in ES6, you have to access symbol properties in Object literals using bracket notation:
let mySymbol = Symbol("mySymbol");
let someObject = {
[mySymbol]: "someValue"
};
console.log(someObject[mySymbol]); // "someValue"
Is there a way to define and access symbol properties using dot notation?
No. Symbols must be accessed using bracket notation.
Dot notation is only used for string keys that follow certain rule patterns, mostly about being a valid identifier.
Symbols are not strings, they are a whole something else entirely.
Short rational: One of the design goals of symbols is that they can not clash with property names, that makes them safe to use.
So, if you had an object like this
var = {
prop1: "Value"
};
And you created a symbol called prop1, how could you tell the two apart, and access them differently, using just object notation?
No. Dot notation is reserved for identifiers which resolve to property names (strings). And this won't change for backward compatibility reasons.
Related
Consider below example:
a={
'firstProperty': "first",
'secondProperty':"second"
};
console.log(a[[[["firstProperty"]]]]);
by using multiple bracket notation i am able to access the firstProperty. How bracket notation is accessing this property??
You are using a nested array and by using a non string or symbol as value, the value is converted to string.
console.log([[["firstProperty"]]].toString());
Because what you provide as the key in a property accessor expression is converted to string if it isn't a Symbol or a string. console.log(a[[[["firstProperty"]]]]); uses an array of arrays as the property name in the accessor expression. Since that isn't a Symbol, it's converted to string. When you convert your array to string, you get the string "firstProperty" because that's how Array.prototype.toString works:
console.log(String([[["firstProperty"]]]));
...and "firstProperty" correctly identifies one of the properties in the object, so the property accessor expression gives you the value of that property.
Using an array like that is unnecessary. Just use
console.log(a["firstProperty"]);
or
console.log(a.firstProperty);
Given an object literal, or jQuery(html, attributes) object, does any specification state that reserved words, or future reserved words MUST be quoted?
Or, can, for example, class be set as a property name of an object without using quotes to surround the property name, without the practice being contrary to a specification concerning identifiers, property names, or use of reserved words?
Seeking a conclusive answer as to this question to avoid confusion.
let objLit = {
class: 123,
var: "abc",
let: 456,
const: "def",
import: 789
}
console.dir(objLit);
jQuery("<div>012</div>", {
class: "ghi"
})
.appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
Related:
What is the difference between object keys with quotes and without quotes?
Comments on this answer
Specification
7.6 Identifier Names and Identifiers:
Identifier Names are tokens that are interpreted according to the
grammar given in the “Identifiers” section of chapter 5 of the Unicode
standard, with some small modifications.
An Identifier is an IdentifierName that is not a ReservedWord
ECMAScript 5+
No, quotes were not needed since ECMAScript 5. Here's why:
As mentioned in your post, from the ECMAScript® 5.1 Language Specification:
7.6 Identifier Names and Identifiers
Identifier Names are tokens that are interpreted according to the grammar given in the “Identifiers” section of chapter 5 of the Unicode standard, with some small modifications. An Identifier is an IdentifierName that is not a ReservedWord (see 7.6.1).
[...]
Syntax
Identifier ::
IdentifierName but not ReservedWord
By specification, a ReservedWord is:
7.6.1 Reserved Words
A reserved word is an IdentifierName that cannot be used as an Identifier.
Syntax
ReservedWord ::
Keyword
FutureReservedWord
NullLiteral
BooleanLiteral
This includes keywords, future keywords, null, and boolean literals. The full list is as follows:
7.6.1.1 Keywords
break do instanceof typeof
case else new var
catch finally return void
continue for switch while
debugger function this with
default if throw
delete in try
7.6.1.2 Future Reserved Words
class enum extends super
const export import
7.8.1 Null Literals
null
7.8.2 Boolean Literals
true
false
The above (Section 7.6) implies that IdentifierNames can be ReservedWords, and from the specification for object initializers:
11.1.5 Object Initialiser
[...]
Syntax
ObjectLiteral :
{ }
{ PropertyNameAndValueList }
{ PropertyNameAndValueList , }
Where PropertyName is, by specification:
PropertyName :
IdentifierName
StringLiteral
NumericLiteral
As you can see, a PropertyName may be an IdentifierName, thus allowing ReservedWords to be PropertyNames. That conclusively tells us that, by specification, it is allowed to have ReservedWords such as class and var as PropertyNames unquoted just like string literals or numeric literals.
ECMAScript <5
To go more in depth as to why this wasn't allowed in previous versions before ES5, you have to look at how PropertyName was defined. Per the ECMAScript® 3 Language Specification:
PropertyName :
Identifier
StringLiteral
NumericLiteral
As you can see, PropertyName was an Identifer - not an IdentifierName, thus leading to the inability for ReservedWords as PropertyNames.
Given an object literal, or jQuery (html, attributes) object, does any specification state that reserved words, or future reserved words MUST be quoted?
No (starting with ES5).
The definition of property in the spec is that it is any identifier name. class is a perfectly good identifier name.
As others have pointed out in the comments, according to the spec, the property name in an object literal may be an (unquoted) IdentifierName (in addition to being a string etc.). IdentifierName is, for all practical purposes, any sequence of Unicode "letters", as given in section 7.6.
Note that the syntax error generated by
const {class} = obj;
is not an exception. That's not an object literal, which is what the question is about; it's an assignment (or the destructuring kind), which attempts to assign a variable class. Of course you can't, never have been able to, and never will be able to have variables which are named with reserved words.
See also this blog post, which although not authoritative is a reliable, high-quality source of information about all things ES5/6/7.
Note that in ES3, the definition of PropertyName was Identifier, not IdentifierName as in ES5. That prevented using properties such as class, since class is not an identifier. It was this change that permitted the use of unquoted reserved words as properties in object literals (as well as in dot notation).
With regard to "jQuery objects", a "jQuery object" is just a regular old JS object. Do you mean the DOM elements held by jQuery objects? They are a kind of hybrid of native objects and JS objects. As JS objects, they can have properties. However, they cannot be written in object literal form, so the question does not really apply to them. (As native (DOM) objects, they can have attributes, the latter case not being covered by the JS spec.)
This answer cannot compete with those already given but I'd love to chime in nonetheless.
In my code I prefer to ALWAYS quote keys, for example:
var o;
o = {
"label": "Hello",
"index": 3
};
This way, the problem of strange names or reserved keywords doesn't even arise. Furthermore, all object literals are written in a style that is very near to valid JSON, as an added bonus copy+paste into a separate JSON file (and vice-versa) can be done very quickly.
Today, I consider this a must-have style for clean code.
I ran into a problem using the Pipedrive API. I tried to get some data using the below but it returned an error:
$.each(data.data, function(key,value) {
console.log(value.0d1df598a5539ab5b6b410b339dc9218e0acb091);
});
However this works:
$.each(data.data, function(key,value) {
console.log(value.person_name);
});
Why can't I get values of the keys that are complex strings generated by the Pipedrive system?
To retrieve what you require you would need to use bracket notation as the first character of the property identifier is an integer. Try this:
var value = {
'0d1df598a5539ab5b6b410b339dc9218e0acb091': 'foo bar'
}
console.log(value['0d1df598a5539ab5b6b410b339dc9218e0acb091']);
A possible explanation can be summarized in two part
Valid javascript variable(identifier names)
An identifier must start with $, _, or any character in the Unicode categories Uppercase letter (Lu), Lowercase letter, Titlecase letter (Lt), Modifier letter (Lm), Other letter (Lo), or Letter number (Nl).
In your case the identifier name start with an integer(0)
Property accessors
An key of an object in js can be retrieved either by using dot (.) notation or by using Bracket[]` notation
Square brackets notation allows use of characters that cannot be used with dot notation and also to retrieve an identifier which is not valid according to the first point.Beside it also allows to access properties containing special characters.
This is because js interpreter automatically converts the expression within square brackets to a string & retrieves the corresponding value.Actually
js evaluates the first complete expression with square brackets in a statement, runs toString() on it to convert it into a string and then uses that value for the next bracket expression, on down the line till it runs out of bracket expressions.
So dot notation has marginal upper-hand since it wont go throught he above process.
But it cannot be use it with a variable(or number).
It only allow to access explicit key name of a property
Since the identifier in your object identifiers's name starts with an 0 , bracket notation like value['0d1df598a5539ab5b6b410b339dc9218e0acb091'] will give it's value.
This question already has answers here:
JavaScript property access: dot notation vs. brackets?
(17 answers)
Closed 5 years ago.
What is the real difference in using [] and . for accessing array or object properties? Which one to use?
Also why doesn't . operator allow the index property?
Accessing members with . is called dot notation. Accessing them with [] is called bracket notation.
The dot notation only works with property names which are valid identifier names [spec], so basically any name that would also be a valid variable name (a valid identifier, see also What characters are valid for JavaScript variable names?) and any reserved keyword [spec].
Bracket notation expects an expression which evaluates to a string (or can be coerced to a string), so you can use any character sequence as property name. There are no limits to what a string can contain.
Examples:
obj.foo; // valid
obj.else // valid, reserved keywords are valid identifier names
obj.42 // invalid, identifier names cannot start with numbers
obj.3foo // invalid, ""
obj.foo-bar // invalid, `-` is not allowed in identifier names
obj[42] // valid, 42 will be coerced to "42"
obj["--"] // valid, any character sequence is allowed
obj[bar] // valid, will evaluate the variable `bar` and
// use its value as property name
Use bracket notation:
When the property name is contained in a variable, e.g. obj[foo].
The property name contains characters not permitted in identifiers, e.g. starts with a digit†, or contains a space or dash (-), e.g. obj["my property"].
Use dot notation: In all other situations.
There is a caveat though regarding reserved keywords. While the specification permits to use them as property names and with the dot notation, not all browsers or tools respect this (notably older IE versions). So the best solution in my opinion is to avoid using reserved keywords for property names or use bracket notation if you cannot.
†: That's also the reason why you can only use bracket notation to access array elements. Identifiers cannot start with digits, and hence cannot consist only of digits.
You should use . when you know the name of the property
var object = {};
object.property = 'whatever';
, use [] when the name of the property is contained in a variable
var object = {};
var property = 'another-property';
object[property] = 'whatever';
As #DCoder added certain object properties cannot be accessed without using the [] notation because their names break the syntax. E.g. properties named class, default, or data-prop-value
Also why doesn't . operator allow the index property? I really want
full reason. Thank you.
Well if that was possible, consider:
var a = 0.5;
Did you mean the number 0.5 or access the 5 element of the number?
See:
Number.prototype[5] = 3;
0[5] //3
0.5 // 0.5
If you allowed the syntax 0.5 to be equal to 0[5], then how do you know what you mean?
It is however possible to use numbers directly with object literal:
var a = {
0: 3,
1: 5
};
Both dot operator and index(bracket notation) operator are used to access the property of an Object. Generally accessing with dot operator is quite faster because accessing variables by window is significantly slower though. But in case of special character
in the variables, you cannot use dot operator as it will give error. For such cases we need to use index operator and pass the variable name as a string format means underdouble quote otherwise it will give undefined error.
e.g-
var abc = {
font-size : "12px"
}
Using dot operator - abc.font-size; //it will give error (Incorrect)
Using index operator - abc["font-size"]; //12px (Correct)
I find myself needing to convert a string var (in JavaScript) to a variable name that is called when getting an element. My spontaneous solution to this was writing:
this.name = name;
[...]
this.context.drawImage(imageRepository.(this.name), this.x, this.y);
This does not work however, returning "Unexpected token (". Any suggestions?
You're looking for a property name, not a variable name. You can use bracketed notation for that:
imageRepository[this.name]
In JavaScript, you can refer to properties in two ways: Using dot notation and a property name literal (obj.foo), or using bracketed notation and a property name string (obj["foo"]). In the latter case, the string can be the result of any expression, including looking up a property on another object (this.name).
You need bracket notation in this case.
imageRepository[this.name]
The bracket notation evaluates the variable and selects the appropriate property.