You Don't Know JS: this & Object Prototypes
6: Behavior Delegation
Behavior delegation suggests objects as peers of each other, which delegate amongst themselves, rather than parent and child class relationships
JavaScript's [[Prototype]] mechanism is, by its very designed nature, a behavior delegation mechanism
OLOO (objects-linked-to-other-objects) is a code style which creates and relates objects directly without the abstraction of classes
OLOO implements [[Prototype]]-based behavior delegation.
5.Prototypes
Objects in JavaScript have an internal property, denoted in the specification as [[Prototype]], which is simply a reference to another object.
The default [[Get]] operation proceeds to follow the [[Prototype]] link of the object if it cannot find the requested property on the object directly
The top-end of every normal [[Prototype]] chain is the built-in Object.prototype
In JavaScript, classes can't describe what an object can do. The object defines its own behavior directly
in JavaScript, it's most appropriate to say that a "constructor" is any function called with the new keyword in front of it.
.prototype
instanceof()
Object.create(..) creates a new object linked to the object we specified which gives us all the power (delegation) of the [[Prototype]] mechanism
4.Mixing (Up) "Class" Objects
Classes are a design pattern. Many languages provide syntax which enables natural class-oriented software design
Classes mean copies
A class is instantiated into object form by a copy operation.
When traditional classes are instantiated, a copy of behavior from class to instance occurs. When classes are inherited, a copy of behavior from parent to child also occurs.
(Super)
Polymorphism (having different functions at multiple levels of an inheritance chain with the same name) may seem like it implies a referential relative link from child back to parent, but it's still just a result of copy behavior.
The mixin pattern (both explicit and implicit) is often used to sort of emulate class copy behavior, but this usually leads to ugly and brittle syntax like explicit pseudo-polymorphism (OtherObj.methodName.call(this, ...)), which often results in harder to understand and maintain code.
Explicit mixins are also not exactly the same as class copy, since objects (and functions!) only have shared references duplicated, not the objects/functions duplicated themselves. Not paying attention to such nuance is the source of a variety of gotchas.
1."this" Or That?
the "this" mechanism provides a more elegant way of implicitly "passing along" an object reference, leading to cleaner API design and easier re-use.
"this" is actually a binding that is made when a function is invoked, and what it references is determined entirely by the call-site where the function is called.
2."this" All Makes Sense Now!
If strict mode is in effect, the global object is not eligible for the default binding, so the "this" is instead set to undefined
though the overall this binding rules are entirely based on the call-site, the global object is only eligible for the default binding if the contents of foo() are not running in strict modeŠ°
When there is a context object for a function reference, the implicit binding rule says that it's that object which should be used for the function call's this binding.
"this" binding creates is when an implicitly bound function loses that binding, which usually means it falls back to the default binding, of either the global object or undefined, depending on strict mode
call(..)
apply(..)
bind(..)
something = new MyClass(..);
Object.create(null) - the prototype of the object refers to null
arrow-function have not "this"!
3.Objects
(Object.prototype.toString...) strObject is an object that was in fact created by the String constructor.(the same situation with other primitive values)
null and undefined have no object wrapper form, only their primitive values.
Objects, Arrays, Functions, and RegExps (regular expressions) are all objects regardless of whether the literal or constructed form is used.
Objects in JS have both a literal form (such as var a = { .. }) and a constructed form (such as var a = new Array(..))
objects can have their mutability (and that of their properties) controlled to various levels of immutability using Object.preventExtensions(..), Object.seal(..), and Object.freeze(..)
Properties don't have to contain values -- they can be "accessor properties" as well, with getters/setters
Properties can also be either enumerable or not, which controls if they show up in for..in loop iterations, for instance.
Object.getOwnPropertyNames(..)
hasOwnProperty(..)
Object.keys(..)
propertyIsEnumerable(..)