Objects

Essential

object - is a collection of key-value pairs

  • variable with an object only contains a pointer to this object. therefore two objects are only equal when they are the same object


key - unique identifier for one property value

  • allowed names: strings (including keywords) and numbers (including float, e and other numeral systems). negative numbers are not allowed
  • all key names are being converted to string
  • order: integer properties are sorted, others appear in creation order


object initializer - syntax for creating an object using a set of key-value pairs enclosed in curly braces

  • also known as object literal


method - function, which is stored in object, as value of object property

  • ways to create method:
  • method: function() {...} - basic method
  • method: () => {...} - arrow function method
  • method() {...} - similar conception to shorthand syntax. this is analog of first variant
  • method - object shorthand syntax. function is stored in "method" variable


object shorthand syntax - syntax which allows omitting key, if it's value is same as variable name

  • e.g. { name } - equals { name: name }


property accessor - term used for syntax, which allows accessing an object property. there are 2 variants of property accessors

  • dot notation - accessing with dot. e.g. object.key
  • square bracket notation - special syntax for accessing properties dynamically. e.g. object[key] - key is variable with some value
  • square bracket notation can also be used for property creation. it allows the following use-cases:
  • [x]: y - create computed property. key name is taken from "y" variable
  • ['property one']: x - create multiword property
  • ['ab' + x]: y - obtain the property name as the result of an expression


accessor property - special type of object property, which looks like property, but internally behaves like method. see Getter & Setter

optional chaining - syntax, which allows accessing deeply nested properties without worrying whether the property exists or not

  • e.g. someObject.noSuchProperty?.foo?.bar - returns undefined
  • users?.[0] - optional chaining for properties which can contain array
  • accessing non-existing property at most data types doesn't trigger error, unless it's function call. accessing at undefined and null triggers error:
  • null.fooProperty -> TypeError: Cannot read properties of null
  • true.fooProperty === undefined
  • true.barMethod() -> TypeError: true.barMethod is not a function


collection - data structure designed for organizing and managing group of related data

  • collection might is not always iterable. e.g. it includes simple object


indexed collection - collection of elements, which are stored at ordered numeric indices. this includes arrays and array-like constructs, e.g. NodeList

  • indexed collection is always an iterable object
  • length - named property, which contains amount of elements in indexed collection
  • named property - property which is present within an indexed collection, but its key is not a numeric index

Constructor

new Object() - create new object

  • const object = {} - more common and easy way of object creation. it is analog of const object = new Object()
  • curly braces don't create scope in this case. so "this" is taken from outside

Static Methods

Object.keys(object) - returns array of own keys

  • tricks:
  • Object.keys(object).length - check whether object is empty
  • Object.keys(object).find(key => object[key] === value) - get the key knowing the value


Object.values(object) - returns array of own values

Object.entries(object) - returns array of entries (array of arrays)

  • entries - are arrays, each with key-value pair


Object.fromEntries(iterable) - receives entries as argument and converts it into an object

Object.is(value1, value2) - check whether two values are equal

  • it is not equivalent neither to "==" nor to "===" comparison
  • "is" does shallow comparison


Object.freeze() - prevent data mutation

Object.hasOwn(object, property) - this is static equivalent of hasOwnProperty method

Object.assign(target, source, sourceN?) - is used to join two or more objects into one. returns updated target

  • target - object properties of which will be extended with "source" properties
  • if the receiving object already has property named the same, it will be overwritten
  • e.g.
  • const clone = Object.assign({}, user) - clone an object
  • const clone = { ...user } - spread operator provides a new handy way of cloning

Instance Methods

hasOwnProperty(key) - checks whether object contains a property, but excludes inherited properties

  • ways of property existence check, considering inherited properties:
  • obj[key] === undefined - simple comparison with undefined. accessing a non-existing property results in undefined
  • 'fooKey' in barObject - "in" operator results in boolean


toString() - returns string representation of an object

  • object might contain custom toString method, which implements custom type conversion logic


valueOf() - converts "this" value to an object

  • object might contain custom toValue method, which implements custom type conversion logic

Destructuring

destructuring - makes it possible to unpack properties from objects, or values from arrays, into distinct variables

Object

const { id, name } = user - destructuring object during assignment. this saves "id" and "name" properties into "id" and "name" variables

  • inherited properties are also considered


const UserComponent = ({ id, name }) => {...} - dectructuring object passed as function parameter

for (let { id, name } of usersArray) {...} - destructuring object within loop

{ post: { title, body, user, comments } } - accessing nested properties

  • in case post is undefined, error will be thrown

{ post: { title: heading } } - giving new names to variables. in such case original name (title) is not accessible
{ operations: [operation] = [{}] } - setting default value for object property

Array

const [foo] = array - destructuring array during assignment. this assigns array's first element to foo

  • besides, same use-cases as for objects are possible for arrays


[ , , foo] - in case some element should be skipped, simple coma can be used. in this case foo takes value of array's third element

Spread & Rest

Spread

spread operator - converts array, object or string into distinct values

  • other types can not be spread, but spreading them doesn't trigger an error
  • tricks:
  • const thisArray = […thatArray] - clone an array
  • const array = [...string] - string to array. analog of split('')
  • const foo = { ...bar, name: 'Bob' } - change an object without mutation
const numbers = [10, 11, 12];
Math.max(…numbers);

Rest

rest operator - converts distinct values into an array or object

  • e.g.
  • const foo = (…args) => {...} - collect all arguments into args array
  • const foo = (bar, ...args) => {...} - save first argument separately and collect all others into args array
  • const [foo, ...other] = array - rest into array in pair with destructuring
  • rest into object is only possible in pair with destructuring
  • e.g. const Bar = ({ children, ...props }) => {...} - children property is saved to variable, all other properties are collected into props object
  • tricks:
  • const newArray = array.map(({ foo, bar, …keepProperties }) => keepProperties) - delete properties from array of objects

JSON

JavaScript Object Notation (JSON) - text-based format for representing JavaScript objects

  • JSON objects are used for data exchange


JSON.stringify(value, replacer, space) - transform object to string

  • tricks:
  • <pre>{JSON.stringify(state, null, 2)}</pre> - data object visualization


JSON.parse() - transform string to object

  • tricks:
  • JSON.parse(JSON.stringify(object)) - deep clone an object, final values of which are simple not functions

Getter & Setter

getter - allows calling a function, when object property is accessed, which return property value. such property can be called a calculating property

  • function doesn't take any arguments
  • advantage of such approach is that function can have access to its object via "this"
  • when used without setter, getter function is still called on property accessing
  • new value can't be assigned, assignment is ignored without an error


setter - allows calling a function, when new value is assigned to object property

  • function takes assignment value as argument
  • when used without getter, setter function is still called on assignment, but accessing the property results in undefined
const user = {
  firstName: 'Bill',
  lastName: 'Gates',
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },
  set fullName(value) {
    const [firstName, lastName] = value.split(' ');

    this.firstName = firstName;
    this.lastName = lastName;
  },
};

user.fullName = 'Steve Jobs';
console.log(user.fullName);

in other words, both getter and setter allow property to look like simple property, but behave similar to a method

Set & Map

keyed collection - alternative to arrays and objects introduced with ES6. it includes Set, Map, WeakSet, WeakMap

  • keyed collection is iterable, since it is indexed
  • iteration over keyed collection happens in the insertion order. keyed collection can't be reordered
  • index can't be used to access element within a set or property within a map

Set

set - a collection of unique values without keys

  • uniqueness is set's main feature. repeated adding of same element into the set is just ignored
  • benefit over array is that element can be accessed by value easily
  • WeakSet - collection of unique values, all of which must be objects


new Set(iterable?) - create Set

  • e.g. const set = new Set([1, 5, 10])
  • tricks:
  • [...new Set(array)] - create array without repetitions


add(value) - adds a value and returns the updated set
delete(value) - removes value and returns boolean. true is value existed, otherwise false
has(value) - returns boolean
clear() - removes everything
size - contains elements count

Map

map - is a collection of key-value pairs. compared to regular object, map is allowed to have keys of any type

  • value under each index is object with "key" and "value" properties
  • benefit over regular object is that map is iterable
  • also map fully preserves the order of insertion, unlike a regular object
  • WeakMap - is a collection of key-value pairs whose keys must be objects


new Map(iterable?) - creates the map

  • iterable - is any iterable object, which will be converted to the map
  • tricks:
  • new Map(Object.entries(object)) - convert Object to Map
  • Object.fromEntries(map) - convert Map to Object
const recipeMap = new Map([
  ['feta', 40],
  ['mustard', 40],
  ['olive oil', 10]
]);

set(key, value)

  • every "set" call returns the map itself, so calls can be chained

get(key)

  • returns undefined if key doesn't exist

has(key) - returns boolean
delete(key)
clear() - removes everything from the map
size - contains element count

keys() – returns MapIterator for keys
values() – returns MapIterator for values
entries() – returns MapIterator for entries. it's used under the hood for map iteration

  • for (let entry of recipeMap) {...} - equals for (let entry of recipeMap.entries()) {...}

Global Object

global object - is an object that is accessible throughout the entire runtime environment


window - in browser
global - in Node.js
self - in web workers
globalThis - always refers to the global object, no matter where the code is being executed

  • ES2020 feature
;