Objects and Destructuring Flashcards
What are objects? Provide an example.
- Explain what objects are and how do they compare to primitive types.
In JavaScript, an object is an unordered collection of key-value pairs. Each key-value pair is called a property.
The key of a property can be a string. And the value of a property can be any value, e.g., a string, a number, an array, and even a function.
A property’s value can be a function, in which case the property is known as a method.
const person = { name: ['Bob', 'Smith'], age: 32, bio: function() { console.log(`${this.name[0]} ${this.name[1]} is ${this.age} years old.`); }, introduceSelf: function() { console.log(`Hi! I'm ${this.name[0]}.`); } };
Summary
- An object is a collection of key-value pairs. - Use the dot notation ( .) or array-like notation ([]) to access a property of an object. - The delete operator removes a property from an object. - The in operator check if a property exists in an object.
How can I access the object’s properties?
To access a property of an object, you use one of two notations:
- the dot notation - array-like notation
dot notation:
objectName.propertyName
array-like notation:
objectName[‘propertyName’]
We use dot notation when we know the name of the property.
We use array-like notation when we DO NOT know the name of the property and we need to ‘construct’ it.
What do we use objects for?
- Demonstrate how we can use objects.
- Explain how objects help build more complex applications.
Objects in JavaScript, just as in many other programming languages, can be compared to objects in real life. The concept of objects in JavaScript can be understood with real life, tangible objects.
In JavaScript, an object is a standalone entity, with properties and type. Compare it with a cup, for example. A cup is an object, with properties. A cup has a color, a design, weight, a material it is made of, etc. The same way, JavaScript objects can have properties, which define their characteristics.
Objects in JavaScript are ubiquitous and versatile. An object can be used as a bag of parameters with several handler functions attached. An object can group associated values but also structure a program. For example, you can put several similar functions on one object and let them operate on the same data.
What are the differences between primitive and reference types? Give code examples.
- Explain the difference between primitive and reference types. - Demonstrate the difference between primitive and reference types.
- Javascript has two types of values: primitive values and reference values.
- You can add, change, or delete properties to a reference value, whereas you cannot do it with a primitive value.
- Copying a primitive value from one variable to another creates a separate value copy. It means that changing the value in one variable does not affect the other.
- Copying a reference from one variable to another creates a reference so that two variables refer to the same object. This means that changing the object via one variable reflects in another variable.
Primitive values: var a = 3.14; // Declare and initialize a variable var b = a; // Copy the variable's value to a new variable a = 4; // Modify the value of the original variable alert(b) // Displays 3.14; the copy has not changed
Reference values: var a = [1,2,3]; // Initialize a variable to refer to an array var b = a; // Copy that reference into a new variable a[0] = 99; // Modify the array using the original reference alert(b); // Display the changed array [99,2,3] using the new reference
What is destructuring, object destructuring?
Object destructuring assigns the properties of an object to variables with the same names by default.
let person = { firstName: 'John', let { firstName: fname, lastName: lname } = person; lastName: 'Doe' };
let { property1: variable1, property2: variable2 } = object;
The identifier before the colon (:) is the property of the object and the identifier after the colon is the variable.
If the variables have the same names as the properties of the object, you can make the code more concise as follows:
let { firstName, lastName } = person;
When you assign a property that does not exist to a variable using the object destructuring, the variable is set to undefined.
In this example we assign the currentAge property to the age variable with the default value of 18:
let { firstName, lastName, middleName = ‘’, currentAge: age = 18 } = person;
A function may return an object or null in some situations. The code will throw a TypeError. To avoid this, you can use the OR operator (||) to fallback the null object to an empty object:
let { firstName, lastName } = getPerson() || {};
Nested object destructuring: Assuming that you have an employee object which has a name object as the property: let employee = { id: 1001, name: { firstName: 'John', lastName: 'Doe' } };
The following statement destructures the properties of the nested name object into individual variables:
let { name: { firstName, lastName } } = employee;
Array destructuring
ES6 provides a new feature called destructing assignment that allows you to destructure elements of an array into individual variables.
Assuming that you have a function that returns an array of numbers as follows:
function getScores() { return [70, 80, 90]; }
Destructing assignment: let [x, y, z] = getScores(); // x = 70, y = 80, z = 90
It’s possible to take all remaining elements of an array and put them in a new array by using the rest syntax (…):
let [x, y ,…args] = getScores(); // [70, 80, 90, 100]; -> x = 70, y = 80, args = [90, 100]
You can skip elements and sent a default values: let [, , thirdItem = 0] = getItems(); // thirdItem = 0
If the getItems() function doesn’t return an array and you expect an array the destructing assignment will result in an error (TypeError):
To avoid the error use this: let [a = 10, b = 20] = getItems() || [];
Nested array destructuring:
function getProfile() {
return [
‘John’,
‘Doe’,
[‘Red’, ‘Green’, ‘Blue’]
];
}
Nested array destructuring: let [ firstName, lastName, [ color1, color2, color3 ] ] = getProfile();
Swapping variables: let a = 10, b = 20; -> [a, b] = [b, a]; // a = 20, b = 10
Spread Operator
- The spread operator is denoted by three dots (…).
- The spread operator unpacks elements of iterable objects such as arrays, sets, and maps into a list.
- The rest paramter is also denoted by three dots (…). However, it packs the remaining arguments of a function into an array.
- The spread operator can be used to clone an iterable object or merge iterable objects into one.
const odd = [1,3,5]; const combined = [2,4,6, ...odd]; // [ 2, 4, 6, 1, 3, 5 ] The spread operator (...) unpacks the elements of the odd array.
Here are the main differences bertween rest and spread operators:
- The spread operator (...) unpacks the elements of an iterable object. - The rest parameter (...) packs the elements into an array. - The rest parameters must be the last arguments of a function. However, the spread operator can be anywhere:
const odd = [1,3,5]; const combined = [2,...odd, 4,6]; // [ 2, 1, 3, 5, 4, 6 ]
JavaScript spread operator and array manipulation
1) Constructing array literal - the spread operator allows you to insert another array into the initialized array when you construct an array using the literal form:
let initialChars = ['A', 'B']; let chars = [...initialChars, 'C', 'D']; // ["A", "B", "C", "D"]
2) Concatenating arrays: you can use the spread operator to concatenate two or more arrays:
let numbers = [1, 2];
let moreNumbers = [3, 4];
let allNumbers = […numbers, …moreNumbers]; // [1, 2, 3, 4]
3) Copying an array: you can copy an array instance by using the spread operator
let scores = [80, 70, 90];
let copiedScores = […scores];
console.log(copiedScores); // [80, 70, 90]
JavaScript spread operator and strings:
let chars = ['A', ...'BC', 'D']; console.log(chars); // ["A", "B", "C", "D"]
Rest Parameters
(…). A rest parameter allows you to represent an indefinite number of arguments as an array.
function fn (a, b, ...args) { //... }
All the arguments you pass to the function will map to the parameter list. In the syntax above, the first argument maps to a, the second one maps to b, and the third, the fourth, etc., will be stored in the rest parameter args as an array.
fn(1, 2, 3, “A”, “B”, “C”); // [3, ‘A’, ‘B’, ‘C’]
The rest parameters must appear at the end of the argument list. The following code will result in an error:
function fn(a, ...rest, b) { // error // SyntaxError: Rest parameter must be last formal parameter }
Assuming that the caller of the sum() function may pass arguments with various kinds of data types such as number, string, and boolean, and you want to calculate the total of numbers only:
function sum(...args) { return args .filter(function (e) { return typeof e === 'number'; let result = sum(10, 'Hi', null, undefined, 20); // 30 }) .reduce(function (prev, curr) { return prev + curr; }); }
Filter the arguments based on a specific type such as numbers, strings, boolean, and null:
function filterBy(type, ...args) { return args.filter(function (e) { return typeof e === type; }); }
Rest parameters and arrow function:
const combine = (...args) => { return args.reduce( (prev, curr) => prev + ' ' + curr); };
let message = combine(‘JavaScript’, ‘Rest’, ‘Parameters’); // JavaScript Rest Parameters
How can I check if an object has a property?
- hasOwnProperty() method
const hero = { name: 'Batman' }; hero.hasOwnProperty('name'); // => true hero.hasOwnProperty('realName'); // => false
- “in” operator
const hero = { name: 'Batman' }; 'name' in hero; // => true 'realName' in hero; // => false
- Comparing with undefined
const hero = { name: 'Batman' }; hero.name; // => 'Batman' hero.realName; // => undefined
But be aware of false negatives. If the property exists but has an undefined value:
const hero = { name: undefined }; hero.name !== undefined; // => false
What is primitive value in JS?
Primitive values are: null, undefined, boolean, number, string, symbol, and BigInt
Static data is the data whose size is fixed at compile time. Static data includes: primitive and reference values.
JavaScript engine stores primitive values and variables on the stack.
let age = 25; let newAge = age;
newAge = newAge + 1; console.log(age, newAge); // newAge = 26 // age =25
What is a reference type value in JS?
When you declare variables, the JavaScript engine allocates the memory for them on two memory locations: stack and heap.
Reference values that refer to objects.
Unlike the stack, JavaScript stores objects (and functions) on the heap. The JavaScript engine doesn’t allocate a fixed amount of memory for these objects. Instead, it’ll allocate more space as needed.
let person = { name: 'John', age: 25, };
let member = person;
member.age = 26;
console. log(person);
console. log(member);
What is the main difference between reference copy and shallow copy?
var obj1 = new object() var obj2 = obj1
Reference copy refers to the fact that both objects refer to the same object without creating a new object. When one object changes, the other object will also change.
Shallow copy will create a new object, this object has an exact copy of the original object property values
- If the attribute is a basic type, the value of the basic type is copied
- If the attribute is a reference type, the memory address is copied (that is, the referenced
object is copied but not the referenced object), so if one of the objects changes this
address, it will affect the other object
What is shallow copy of an object?
A shallow copy will create a new object, this object has an exact copy of the original object’s property values
- If the attribute is a basic type, the value of the basic type is copied
- If the attribute is a reference type, the memory address is copied (that is, the referenced
an object is copied but not the referenced object). So if one of the objects changes this
address, it will affect the other object
What is a deep copy of an object?
A deep copy will create a new heap memory to store an identical object. The old and new objects will not interfere.
A deep copy occurs when an object and the object it refers to are copied together. Deep copy is slower and more expensive than the shallow copy.
The two objects before and after the copy do not affect each other.
How can I make shallow copy of an object?
1. Object.assign( {}, object); const personCopy = Object.assign({}, person);
2. Spread operator const personCopySpread = { ...person };
3. Object with JSON parse and stringify const personCopyJSON = JSON.parse(JSON.stringify(person));
Deep copy, but does not copy functions!
const person = { name: 'Maria', age: 20, courses: ['Math', 'Literature'], sayHello: function () { console.log('Hello'); }, };