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(..)