minor fixes
This commit is contained in:
parent
d1a455080d
commit
f9feec2d69
7 changed files with 64 additions and 60 deletions
|
@ -101,7 +101,9 @@ For multiword properties, the dot access doesn't work:
|
|||
user.likes birds = true
|
||||
```
|
||||
|
||||
That's because the dot requires the key to be a valid variable identifier. That is: no spaces and other limitations.
|
||||
JavaScript doesn't understand that. It thinks that we address `user.likes`, and then gives a syntax error when comes across unexpected `birds`.
|
||||
|
||||
The dot requires the key to be a valid variable identifier. That implies: contains no spaces, doesn't start with a digit and doesn't include special characters (`$` и `_` are allowed).
|
||||
|
||||
There's an alternative "square bracket notation" that works with any string:
|
||||
|
||||
|
@ -203,43 +205,6 @@ Square brackets are much more powerful than the dot notation. They allow any pro
|
|||
|
||||
So most of the time, when property names are known and simple, the dot is used. And if we need something more complex, then we switch to square brackets.
|
||||
|
||||
|
||||
|
||||
````smart header="Reserved words are allowed as property names"
|
||||
A variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc.
|
||||
|
||||
But for an object property, there's no such restriction. Any name is fine:
|
||||
|
||||
```js run
|
||||
let obj = {
|
||||
for: 1,
|
||||
let: 2,
|
||||
return: 3
|
||||
};
|
||||
|
||||
alert( obj.for + obj.let + obj.return ); // 6
|
||||
```
|
||||
|
||||
Basically, any name is allowed, but there's a special one: `"__proto__"` that gets special treatment for historical reasons. For instance, we can't set it to a non-object value:
|
||||
|
||||
```js run
|
||||
let obj = {};
|
||||
obj.__proto__ = 5;
|
||||
alert(obj.__proto__); // [object Object], didn't work as intended
|
||||
```
|
||||
|
||||
As we see from the code, the assignment to a primitive `5` is ignored.
|
||||
|
||||
That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys.
|
||||
|
||||
In that case the visitor may choose `__proto__` as the key, and the assignment logic will be ruined (as shown above).
|
||||
|
||||
There is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects.
|
||||
|
||||
There's also another data structure [Map](info:map-set), that we'll learn in the chapter <info:map-set>, which supports arbitrary keys.
|
||||
````
|
||||
|
||||
|
||||
## Property value shorthand
|
||||
|
||||
In real code we often use existing variables as values for property names.
|
||||
|
@ -284,7 +249,63 @@ let user = {
|
|||
};
|
||||
```
|
||||
|
||||
## Existence check
|
||||
## Property names limitations
|
||||
|
||||
Property names (keys) must be either strings or symbols (a special type for identifiers, to be covered later).
|
||||
|
||||
Other types are automatically converted to strings.
|
||||
|
||||
For instance, a number `0` becomes a string `"0"` when used as a property key:
|
||||
|
||||
```js run
|
||||
let obj = {
|
||||
0: "test" // same as "0": "test"
|
||||
};
|
||||
|
||||
// both alerts access the same property (the number 0 is converted to string "0")
|
||||
alert( obj["0"] ); // test
|
||||
alert( obj[0] ); // test (same property)
|
||||
```
|
||||
|
||||
**Reserved words are allowed as property names.**
|
||||
|
||||
As we already know, a variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc.
|
||||
|
||||
But for an object property, there's no such restriction. Any name is fine:
|
||||
|
||||
```js run
|
||||
let obj = {
|
||||
for: 1,
|
||||
let: 2,
|
||||
return: 3
|
||||
};
|
||||
|
||||
alert( obj.for + obj.let + obj.return ); // 6
|
||||
```
|
||||
|
||||
We can use any string as a key, but there's a special property named `__proto__` that gets special treatment for historical reasons.
|
||||
|
||||
For instance, we can't set it to a non-object value:
|
||||
|
||||
```js run
|
||||
let obj = {};
|
||||
obj.__proto__ = 5; // assign a number
|
||||
alert(obj.__proto__); // [object Object] - the value is an object, didn't work as intended
|
||||
```
|
||||
|
||||
As we see from the code, the assignment to a primitive `5` is ignored.
|
||||
|
||||
The nature of `__proto__` will be revealed in detail later in the chapter [](info:prototype-inheritance).
|
||||
|
||||
As for now, it's important to know that such behavior of `__proto__` can become a source of bugs and even vulnerabilities if we intend to store user-provided keys in an object.
|
||||
|
||||
The problem is that a visitor may choose `__proto__` as the key, and the assignment logic will be ruined (as shown above).
|
||||
|
||||
Later we'll see workarounds for the problem:
|
||||
1. We'll see how to make an objects treat `__proto__` as a regular property in the chapter [](info:prototype-methods).
|
||||
2. There's also study another data structure [Map](info:map-set) in the chapter <info:map-set>, which supports arbitrary keys.
|
||||
|
||||
## Property existance test, "in" operator
|
||||
|
||||
A notable objects feature is that it's possible to access any property. There will be no error if the property doesn't exist! Accessing a non-existing property just returns `undefined`. It provides a very common way to test whether the property exists -- to get it and compare vs undefined:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue