Plain or literal objects : instances of Object class, made via {} notation.

Class objects are instances of classes, via class notation.

Property Descriptors

describes a property of object via a flag object. Properties can be data or accessors

const flags  = {
  value : 'Mayank', writable : true, enumerable : true, configurable : true,
  get() {},
  set() {},
}

Set descriptors

Object.defineProperty(obj, 'name', flags) //will overwrite
Object.defineProperties(obj, {name: flags})
Object.getOwnPropertyDescriptor(obj, 'name')
Object.getOwnPropertyDescriptors(obj)

Shallow v/s Deep copy

//deep copy + circular references
structuredClone(obj)

//shallow copy [OBJECT COMPOSITION]
Object.assign({}, src1, src2, src3)

//copy symbols too 
clonee = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj))

Prototypal Inheritance

Object.prototype.__proto__ === null //this has no prototype

//extend Builtin objects
Date.prototype.nextDay = function() { ... }

Classes are syntactic sugar for prototype-based constructor functions, with enhancements