Presenter: Yauheni Pozdnyakov
t.me/youhy
Primitives
and...
Boxing
Unboxing
Primitives
Object constructors
var a = 5;
let b = 'I love JS'
const iReallyDo = true; //nothing but primitives
a.toString(); //"5"
b.toUpperCase(); //"I LOVE JS"METHOD CALL OVER A PRIMITIVE???? WHAT???
let a = 'I love js ';
a.toUpperCase();
IT'S OKAY!
a - primitive
let's pack it...
var tempA = new String(a)
typeof tempA // object
let's call toUpperCase() method from String object over tempA
tempA// I LOVE JS
unbox tempA to a
a// I LOVE JS
STILL PRIMITIVE!!!
let length = 'this is string'.length; //what you see
let length = (new String('this is string')).length; // what is done
function A() {}Inner properties [[Construct]] and Prototype
function A(){}
A(); // call A as a function
var a = new A(); // call for [[Constructor]] to create an instance of AJavaScript’s object system is based on prototypes, not classes.
const Coder= function(name, lang) {
this.name = name;
this.lang = lang;
this.code = () => `${this.name} codes ${this.lang}`;
};
const john = new Coder('John', 'JavaScript');
const mary = new Coder('Mary', 'GoLang');
john.code() // John codes JavaScript
mary.code() // Mary codes GoLangconsole.log(john.constructor); // function Coder(name, lang) { ... };
console.log(john.constructor.name); // Coder
console.log(john instanceof Coder); // true
Constructor property is assigned to each function created with "new" and points to the Constructor function, which has created this instance
Each time creates function and with code function inside of it.
let a=25;
a.constructor === Number//????const Coder= function(name, lang) {
this.name = name;
this.lang = lang;
};
Coder.prototype.code = function(){
return `${this.name} codes ${this.lang}`
};
const john = new Coder('John', 'JavaScript');
john.code() // John codes Javascript
Creates prototype object
Places code function inside of it
No need to copy code function to each instance of Coder
code method is accessed by _proto_ link from Coder instance to Coder.prototype object
Array.prototype.shift()
[].shift()
Any difference?
console.dir([].__proto__); // same as
console.dir(Array.prototype);
WHY???
// For Numbers
console.dir((10).__proto__); // Number
console.dir((10).__proto__.__proto__); // Object
// For Strings
console.dir('str'.__proto__); // String
console.dir('str'.__proto__.__proto__); // Object
// For objects
console.dir([].__proto__); // Array
console.dir([].__proto__.__proto__); // Object
// For Coder
console.dir(john.__proto__); // Coder
console.dir(john.__proto__.__proto__); // ObjectIf a property is not found on the object, the lookup is delegated to the delegate prototype, which may have a link to its own delegate prototype, and so on up the chain until you arrive at`Object.prototype`, which is the root delegate.
Prototype delegation
_proto_ chaining (looking for methods in chain of prototypes)
Class Inheritance: A class is a description of the object to be created. Classes inherit from classes and create subclass relationships:class hierarchy
May or may not use "class" keyword from ES6
Prototypal Inheritance: A prototype is a working object instance. Objects inherit directly from other objects.
Single-ancestor parent/child hierarchies and create the tightest coupling available in OO design.
Instances are typically instantiated via factory functions, object literals, or `Object.create()`.
`C` calls `super`, which runs code in `B`. `B` calls `super` which runs code in `A`.
A` and `B` contain unrelated features needed by both `C` & `D`. `D` is a new use case, and needs slightly different behavior in `A`’s init code than `C` needs. So the newbie dev goes and tweaks `A`’s init code. `C` breaks because it depends on the existing behavior, and `D` starts working.
`Object.assign()` ES6
Underscore/Lodash’s `.extend()`
We have features:
| Features list |
|---|
| feat1 |
| feat2 |
| feat3 |
| feat4 |
`C` needs `feat1` and `feat3`
`D` needs `feat1`, `feat2`, `feat4`
const C = compose(feat1, feat3);
const D = compose(feat1, feat2, feat4);D needs something different from feat1??
No problem! Let's customise feat1 for D not affecting for others
const D = compose(custom1, feat2, feat4);And `C` remains unaffected!
ES6 classes desugar to constructor functions, so everything that follows about constructor functions also applies to ES6
Required `new`