🚩attribute
(value/writable) | (get/set) / enumerable / configurable
JS ⟩ value ⟩ object ⟩ property ⟩ attribute
only copies the values of enumerable properties, not their attributes❗
if one of the source objects has an accessor property, it is the value returned by the getter that is copied to the target object, not the getter itself❗
non-writable only means that the value can't be reassigned directly.
if configurable, all the attributes could be changed or overwritten completely (data <-> accessor).
property descriptor - the attributes of an object.
property enumeration - how methods enumerate properties.
obj.mergeWith() - copy properties (and their attributes) from other sources.
Object.assign() copies source's own enumerable properties to target.
replit ⟩ property attributes , require ⟩ Object extension
// ⭐ import
const _Object = require('./ext/Object_ext.js'); // extend Object.prototype
// ---------------------------------------------------------------------------
// ⭐ property attributes
// ----------------------------------------------
// • configurable: can change attributes
// • writable : can reassign value
// • enumerable : listed in loops (for-of, ...)
// ⭐ configurable properties
const obj = {
data: 1, // data (writable)
get getter() { return this.data }, // accessor (getter)
set setter(v) { }, // accessor (setter only)
get gSetter() { return this.data }, // accessor (getter/setter)
set gSetter(v) { },
};
// ⭐ non-configurable properties
obj.defineProperties({
x: { value: 1, writable: true }, // data (⭐ writable) (value can be reassigned)
y: { value: 2 }, // data (⭐ non-writable)
z : { // accessor (getter)
get() { return "hello" }
},
});
// ⭐ log
// -------------------------------
// configurable properties
// -------------------------------
// ✅ redefine property
// 1. data -> getter/setter
obj.data, // 1
obj.defineProperty('data', { get() { return 2 } }),
obj.propertyDescriptor('data'),
// { get: [Function], set: undefined, enumerable: true, configurable: true }
// 2. getter/setter -> (non-writable) data
obj.getter, // 2
obj.defineProperty('getter, { value: 'hi' }),
obj.propertyDescriptor('getter'),
// { value: 'hi', writable: false, enumerable: true, configurable: true }
obj.setter = 3, // 3
obj.defineProperty('setter', { value: 'jo' }),
obj.propertyDescriptor('setter'),
// { value: 'jo', writable: false, enumerable: true, configurable: true }
obj.gSetter = 4, // 4
obj.defineProperty('gSetter', { value: 'bravo' }),
obj.propertyDescriptor('gSetter'),
// { value: 'bravo', writable: false, enumerable: true, configurable: true }
// -----------------------------------
// non-configurable properties
// -----------------------------------
// 1. reassign value
// writable
obj.x = 5, // ✅ OK
// non-writable
obj.y = 6, // ⛔ TypeError (fails "silently" in sloppy mode❗)
// Cannot assign to read only property 'y' of object
// 2. redefine property
obj.defineProperty('z', { value: 'hi' }), // ⛔ TypeError
// Cannot redefine property: 'z'replit ⟩ Object_ext.js
// -----------------------------
// ⭐️ extending Object.prototype
// -----------------------------
Object.defineProperties(Object.prototype, {
// 🔸 obj.defineProperty(prop, desc)
defineProperty: {
value: function(prop, descr) {
return Object.defineProperty(this, prop, descr);
},
},
// 🔸 obj.defineProperties(desc)
defineProperties: {
value: function(descr) {
return Object.defineProperties(this, descr);
},
},
// 🔸 obj.propertyDescriptor(prop)
propertyDescriptor: {
value: function(prop) {
return Object.getOwnPropertyDescriptor(this, prop);
},
},
// 🔸 obj.prototype
prototype: {
get: function() {
return Object.getPrototypeOf(this);
},
},
});Last updated
Was this helpful?