diff --git a/notes/chap6_objects.md b/notes/chap6_objects.md index 2fb03fd..7130973 100644 --- a/notes/chap6_objects.md +++ b/notes/chap6_objects.md @@ -146,10 +146,94 @@ function computeValue(portfolio) { ### 6.3.2 Inheritance +JS obj have a set of "own properties", and they also inherit properties from prototype chain. + +Read properties: +* If a property cannot be found in a JS obj, it will search one by one (bottom to top, from child to parent) through prototype chain + +```js +let o = {}; // o inherits object methods from Object.prototype +o.x = 1; // and it now has an own property x. +let p = Object.create(o); // p inherits properties from o and Object.prototype +p.y = 2; // and has an own property y. +let q = Object.create(p); // q inherits properties from p, o, and... +q.z = 3; // ...Object.prototype and has an own property z. +let f = q.toString(); // toString is inherited from Object.prototype +q.x + q.y // => 3; x and y are inherited from o and p +``` + +Write (assign) properties: +* check prototype chain only to verify whether read-only. +* If inherited property `x` is read-only, assignment is not allowed +* If assignment is allowed, the property is created/set within the current object, and do not modify prototype chain +* Only exception: if `o` inherits property `x`, and that property is an accessor property with a setter method, then the setter method is called rather than creating a new property `x` within `o`. + +```js +let unitcircle = { r: 1 }; // An object to inherit from +let c = Object.create(unitcircle); // c inherits the property r +c.x = 1; c.y = 1; // c defines two properties of its own +c.r = 2; // c overrides its inherited property +unitcircle.r // => 1: the prototype is not affected +``` + ### 6.3.3 Property Access Errors +Errors during accessing property: +* It's not error to query a property/object that does not exist. Return `undefined` +* It's error to query property of an non-existent object. Return `TypeError` + +Query non-exist object +```js +book.subtitle // => undefined: property doesn't exist +``` + +Query property of an non-exist object +```js +let len = book.subtitle.length; // !TypeError: undefined doesn't have length +``` + +Method to guard against this problem type: +* Method 1: verbose and explicit +```js +let surname = undefined; +if (book) { + if (book.author) { + surname = book.author.surname; + } +} +``` + +* Method 2: A concise and idiomatic alternative to get surname or null or undefined + * Check Chap4.10.1 for short-circuiting behavior of && operator +```js +surname = book && book.author && book.author.surname; +``` + +* Method 3: Rewrite method 2 using `?.` +```js +let surname = book?.author?.surname; +``` + +Lists of tips: +* Attempting to set property on `null` or `undefined` causes a `TypeError` +* Attempting to set property may fail due to + * Some properties are read-only + * Some objects don't allow adding new properties +* Error from property assignment: + * In strict mode (Chap 5.6.3), a TypeError is thown whenever an attempt to set a property fails. + * Outsie strict mode, silent when fail + +3 circumstances when failed to set a property `p` of obj `o`: +1. `o` has an own property `p` that is read-only +2. `o` has an inherited property `p` that is read-only: No way to overwrite this property +3. `o` does not have an own property `p`; `o` does not inherit a property `p` with a setter method, and `o`’s extensible attribute (see §14.2) is `false`. + 1. Since `p` does not already exist in `o`, and if there is no setter method to call, then `p` must be added to `o`. + 2. But if `o` is not extensible, then no new properties can be defined on it. + ## 6.4 Deleting Properties + + ## 6.5 Testing Properties ## 6.6 Enumerating Properties