Objects: the basics Flashcards
What is an object datatype in JS ?
As we know from the chapter Data types, there are eight data types in JavaScript. Seven of them are called “primitive”, because their values contain only a single thing (be it a string or a number or whatever).
In contrast, objects are used to store keyed collections of various data and more complex entities. In JavaScript, objects penetrate almost every aspect of the language. So we must understand them first before going in-depth anywhere else.
An object can be created with figure brackets {…} with an optional list of properties. A property is a “key: value” pair, where key is a string (also called a “property name”), and value can be anything.
We can imagine an object as a cabinet with signed files. Every piece of data is stored in its file by the key. It’s easy to find a file by its name or add/remove a file.
How to declare an empty object ? Write two methods.
let user = new Object(); // "object constructor" syntax let user = {}; // "object literal" syntax
What is a property in an object ?
let user = { // an object
name: “John”, // by key “name” store value “John”
age: 30 // by key “age” store value 30
};
A property has a key (also known as “name” or “identifier”) before the colon “:” and a value to the right of it.
In the user object, there are two properties:
The first property has the name “name” and the value “John”.
The second one has the name “age” and the value 30.
How to access a property of an object ?
Property values are accessible using the dot notation:
// get property values of the object:
alert( user.name ); // John
alert( user.age ); // 30
The value can be of any type. Let’s add a boolean one:
user.isAdmin = true;
How to delete a property of an object ?
To remove a property, we can use delete operator:
delete user.age;
Can we use multi word property name for an object ?
We can also use multiword property names, but then they must be quoted:
let user = { name: "John", age: 30, "likes birds": true // multiword property name must be quoted };
Why the last property ends with a comma ?
The last property in the list may end with a comma:
let user = { name: "John", age: 30, } That is called a “trailing” or “hanging” comma. Makes it easier to add/remove/move around properties, because all lines become alike.
How to access multi word properties of an object ?
For multiword properties, the dot access doesn’t work:
// this would give a syntax error user.likes birds = true 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 ($ and _ are allowed).
There’s an alternative “square bracket notation” that works with any string:
let user = {};
// set user["likes birds"] = true;
// get alert(user["likes birds"]); // true
// delete delete user["likes birds"]; Now everything is fine. Please note that the string inside the brackets is properly quoted (any type of quotes will do).
Can we access a property from another variable ?
yes
Square brackets also provide a way to obtain the property name as the result of any expression – as opposed to a literal string – like from a variable as follows:
let key = “likes birds”;
// same as user["likes birds"] = true; user[key] = true; Here, the variable key may be calculated at run-time or depend on the user input. And then we use it to access the property. That gives us a great deal of flexibility.
let user = { name: "John", age: 30 };
let key = "name"; alert( user.key ) // Will this work ?
let user = { name: "John", age: 30 };
let key = "name"; alert( user.key ) // undefined Because dot operator doesn't work like that
What are computed properties ?
We can use square brackets in an object literal, when creating an object. That’s called computed properties.
For instance:
let fruit = prompt(“Which fruit to buy?”, “apple”);
let bag = { [fruit]: 5, // the name of the property is taken from the variable fruit };
alert( bag.apple ); // 5 if fruit=”apple”
The meaning of a computed property is simple: [fruit] means that the property name should be taken from fruit.
So, if a visitor enters “apple”, bag will become {apple: 5}.
let fruit = 'apple'; let bag = { [fruit + 'Computers']: 5 // What does this line mean if we write it in dot operator form ? };
let fruit = 'apple'; let bag = { [fruit + 'Computers']: 5 // bag.appleComputers = 5 };
Are thier any name limitations for 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:
// these properties are all right let obj = { for: 1, let: 2, return: 3 };
alert( obj.for + obj.let + obj.return ); // 6
In short, there are no limitations on property names. They can be any strings or symbols (a special type for identifiers, to be covered later).
Other types are automatically converted to strings.
let obj = { 0: "test" }; alert( obj["0"] ); alert( obj[0] );
Will this work ?
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)
Is it possible to access any non existing property of an object. Will there be any error ?
No.
A notable feature of objects in JavaScript, compared to many other languages, is that it’s possible to access any property. There will be no error if the property doesn’t exist!
Reading a non-existing property just returns undefined. So we can easily test whether the property exists:
let user = {};
alert( user.noSuchProperty === undefined ); // true means “no such property”
What is ‘in’ operator ?
The syntax is:
“key” in object
For instance:
let user = { name: “John”, age: 30 };
alert( “age” in user ); // true, user.age exists
alert( “blabla” in user ); // false, user.blabla doesn’t exist
Do we have to use the ‘in’ operator for checking any property existence in a object. Can’t we directly use undefined comparison ?
Why does the in operator exist? Isn’t it enough to compare against undefined?
Well, most of the time the comparison with undefined works fine. But there’s a special case when it fails, but “in” works correctly.
It’s when an object property exists, but stores undefined:
let obj = { test: undefined };
alert( obj.test ); // it’s undefined, so - no such property?
alert( “test” in obj ); // true, the property does exist!
In the code above, the property obj.test technically exists. So the in operator works right.
Situations like this happen very rarely, because undefined should not be explicitly assigned. We mostly use null for “unknown” or “empty” values. So the in operator is an exotic guest in the code.
How for in loop works ?
To walk over all keys of an object, there exists a special form of the loop: for..in. This is a completely different thing from the for(;;) construct that we studied before.
The syntax:
for (key in object) { // executes the body for each key among object properties } For instance, let’s output all properties of user:
let user = { name: "John", age: 30, isAdmin: true };
for (let key in user) { // keys alert( key ); // name, age, isAdmin // values for the keys alert( user[key] ); // John, 30, true }
Are properties ordered inside the object ?
The short answer is: “ordered in a special fashion”: integer properties are sorted, others appear in creation order. The details follow.
As an example, let’s consider an object with the phone codes:
let codes = { "49": "Germany", "41": "Switzerland", "44": "Great Britain", // .., "1": "USA" };
for (let code in codes) {
alert(code); // 1, 41, 44, 49
}
let user = { name: "John", surname: "Smith" }; user.age = 25; // add one more
for (let prop in user) {
alert( prop );
}
What would be the output ?
let user = { name: "John", surname: "Smith" }; user.age = 25; // add one more
// non-integer properties are listed in the creation order for (let prop in user) { alert( prop ); // name, surname, age }
if the keys are non-integer, then they are listed in the creation order,
let codes = { "+49": "Germany", "+41": "Switzerland", "+44": "Great Britain", // .., "+1": "USA" };
for (let code in codes) {
alert( +code );
}
Output ?
let codes = { "+49": "Germany", "+41": "Switzerland", "+44": "Great Britain", // .., "+1": "USA" };
for (let code in codes) {
alert( +code ); // 49, 41, 44, 1
}
to fix the issue with the phone codes, we can “cheat” by making the codes non-integer. Adding a plus “+” sign before each code is enough.
A variable assigned to an object stores not the object itself, but its “address in memory” – in other words “a reference” to it.
Is it true ?
Yes
When an object variable is copied, the reference is copied, but the object itself is not duplicated. Is it true ?
Yes
let a = {}; // empty object let b = a;
alert( a == b );
alert( a === b );
Output ?
let a = {}; // empty object let b = a; // copy the reference
alert( a == b ); // true, both variables reference the same object
alert( a === b ); // true