Objects Flashcards
Ways to define a property in an object
- With literal notation
- Object.defineProperty(obj, ‘key’, {
configurable - if set to false, the value can’t be modified (changed or deleted),
enumerable - if set to false, the property can’t be iterated over,
writable - if set to false value can’t be changed
}) - Object.defineProperties(obj, {
‘key1’: {
configurable: …, writable: …, enumerable: …
},
‘key2’: {…},
…
})
Ways to get a certain Object’s property
- Accessing it directly: obj.key, obj[‘key’]
- Object.getOwnPropertyDescriptor(obj, ‘key’) - returns { value: …, enumerable: …, writable: …, configurable: … }
3*. obj.hasOwnProperty(‘key’) - checks if an Object has a certain property
Ways to get all* properties of the Object
- Using an iterator (does not include non-enumerable properties):
for(let key in obj) { … } - Object.keys(obj) (does not include non-enumerable properties)
- Object.getOwnPropertyNames(obj) - includes non-enumerable properties
Preventing modifications of an Object
- Object.freeze(obj) - prevents from adding new properties and from deleting or changing existing properties.
Object.isFrozen(obj) - checks if object is frozen - Object.preventExtensions(obj) - prevents adding new properties to the Object
Object.isExtensible(obj) - checks if an Object is extensible - Object.seal(obj) - prevents adding new properties or deleting existing ones
Object.isSealed(obj) - checks if Object is sealed
Calling Objects
Problem: I have a method of an Object obj1 and want call it for another Object obj2 (in context of another object)
Solutions:
- Function.call: obj1.method.call(obj2, arg1, arg2, … )
- Function.apply: obj1.method.apply(obj2, [arg1, arg2, … ])
The only difference is that one accepts a list of arguments and the other one expects an array of arguments
Ways to create an Object
- Literal notation: const obj = {}
- Object.create(obj or Object.prototype, { key: { value: …, writable: …, … } }) - creates an object based on the supplied prototype with given values
- new constructor(arg1, arg2, … ) - new operator creates an instance of an object, accepting a constructor function and a series of of optional arguments for the constructor function.
How does ‘new’ operator work?
const obj = new constructor(args)
- JS creates a new object
- JS links the constructor of obj to the supplied constructor function
- JS links the obj.prototype to the constructor.prototype by reference
- JS assigns any supplied args to the obj
OOP-1: Abstraction. Decoupling
Abstraction is an invented construct that transforms a real-life object into a set of values and methods.
Abstractions give a mechanism for a process known as decoupling - breaking up complexities of the subject into smaller parts.
Goals of abstraction:
1. Hiding information
2. Decoupling contents into modules
3. Defining a clear interface between objects
OOP-2: Encapsulation
Goals:
- Hide implementation
- Promote modularity
- Protect the internal state of an object
In ES5 encapsulation can be achieved by using local variables in the constructor function
OOP-3: Polymorphism
Polymorphism describes the capability of one object to act like another in the given context.
Ad hoc polymorphism provides the ability to use the context of the call to an object unrelated to the function.
OOP-4: Inheritance
Inheritance defines semantic hierarchies between objects, by allowing children to create specializations, generalizations and variations of a parent class.
In JS inheritance is prototypal, meaning that it uses prototype chains.
Ways of accessing Prototype
- Given a constructor() function, constructor.prototype will define the prototype for all objects created using ‘new constructor()’
- Object.getPrototypeOf(obj) returns the prototype of an object
- obj.__proto__ is the same as previous method and should not be used, it is mentioned for the sake of completeness
ES6! Classes-1: defining classes
Classes in ES6 are a syntax sugar over the prototyping chain. They can be defined in two ways:
1. Class declaration: class Class { constructor() { ... } } 2. Class expressions that can be named or unnamed: let Class = class ClassName* { constructor() { ... } }
- is optional
ES6! Classes-2: Constructor. Private and public fields
Constructor is a special method for creating and initializing an object created with a class. Constructor can use a super() keyword to call a constructor of a parent class.
Public and private fields can be defined before the constructor or inside constructor after super() runs. Private fields are marked with a # (i. e. this.#privateField)
ES6! Classes-3: Static fields
Static fields and methods do not belong to any instance of a class, but to the class itself. For example if we were to have a class [Class] with a static method [stat()] and there was an instance of this class [inst], then static method wouldn’t be available to the instance [inst.stat() wouldn’t work] but it can be called from the class itself [Class.stat()]