The werid this
2020-08-13Disclaimer
This article is originally based on my understanding of this concept. No guarantee on the accuracy.😅
The weird This
This
was property of a certain context, that is to say, in global context or a function contexThe ECMA 2015
Note:
A Reference
is a resolved name binding. A Reference consists of three components, the base value
, the referenced name and the Boolean valued strict reference flag. The base value is either undefined, an Object, a Boolean, a String, a Number, or an environment record
1 | var foo = (){console.log(this.value)}; |
- In
strict mode
,This
in global context refers to undefined, innon-strict mdoe
it refers to the window object - Inside a function ,
This
pointer was determined when the function was invoked:- During the creation phase the
this
was initialized asundefined
- Then during the execution phase the
this
- Therefore, whom the
This
pointer points to, is subjected to how the funciton was called, which means what is on the left of the()
operator
- During the creation phase the
- A function can be invoked in the following ways by different
CallExpression
- Function invocation => CallExpression Arguments
- Method invocation => CallExpression [ Expression ] CallExpression . IdentifierName
- Constructor invocation => new MemberExpression Arguments
- Indirect invocation =>MemberExpression Arguments
Function inovation & method invoation
- When a function is called as a method of an object, the object is passed to the function as its this value.
1 | let value = 'window'; |
foo()
foo->MemberExpression=>ref: foo => declaritive enviorment record => global object
obj.foo()
obj.foo => ref=> base=>obj
obj.inner.foo()
obj.inner.foo => base => inner
(obj.foo=obj.foo)()
‘=’ assignmetn oprator ->call GetValue -> return a value not a reference => global
doFoo(fn)=>fn()
arguments: fn = obj.foo => call GetValue -> return a value not a reference => global
Constructor invocation
According to ECMA2015, the new operator would call the [[construct]] inner method of a function
Let obj be a newly created native ECMAScript object.
Let result be the result of calling the [[Call]] internal property of F, providing obj as thethis
value and providing the argument list passed into [[Construct]] as args.
If Type(result) is Object then return result.
Return obj.
1 | var name = 'window' |
Arrow function
Promise A+
2020-08-12Disclaimer
This article is originally based on my understanding of this concept. No guarantee on the accuracy.😅
[toc]
Promise A+ step by step
A promise represents the eventual result of an asynchronous operation
State Machine
States: ‘pending’;’fulfilled’;’rejected’;
1 | const PENDING = 'pending'; |
executor
executor will be executed immediately, it takes two function as parameters
1 | function Promise(executor){ |
resolve & reject function
these two function are to
- pass the async results outside for chaining which avoids
nested callback
- change the state of current promise instance;
Only when the state is PENDING, a transition can be made;
1 | const resolve=(value)=>{ |
then
chain revoke => Promise.prototype.then(onRes,onRej)
Methods in then
can obtain the value passed from the promise instance => use this
=>pass the value/reason out by passing them into the resolve/rejection function
1 | Promise.prototype.then = function(onFulfilled, onRejected){ |
1 | //constructor: |
then() returns a new promise instance
1 | const promise2 = new Promise((resolve, reject) => {}) |
the new promise instance, can keep calling then
on itself and pass the previous value/reason to the next then
by passing it to the resolve and reject functions of itself.
If
onFulfilled
is not a function andpromise1
is fulfilled,promise2
must be fulfilled with the same value aspromise1
.If
onRejected
is not a function andpromise1
is rejected,promise2
must be rejected with the same reason aspromise1
.
the result (value/reson) should ‘penetrate’ to the next then.
Providing a default function: (value)=>value
1 | onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; |
so when onFulfilled /onRejected are not function , promise2:
1 | //let x=onFulfilled(this.value)==>this.value |
1 | const promise2 = new Promise((resolve, reject) => { |
es6ds
2020-06-15ES6 Data Type
Disclaimer
This article is originally based on my understanding of this concept. No guarantee on the accuracy.😅
A summary of data type that introduced in ES6.
Type | Symbol | Map | Set |
---|---|---|---|
Summary | Unique ‘string’ | Ordered ‘object’ whose key can be primitive & reference | ‘Array’ with all unique value |
Construct | let sb = Symbol() | let m = new Map([iteratble]) | let s = new Set([iteratble]) |
Key-value | Description as ‘key’ Symbol.keyFor(sb) |
key=>any type ordered value=>any type |
key<=>value unique key |
Loop | N\A | For…of forEach() | for…of forEach() |
Transfer | sb.toString() | […m] = Array.from(m) <=> new Map(arr). | […s] = Array.from(s) <=> new Set(arr). |
Symbol
An unique ‘string’ that would never be equvlient to others
primitive data type
Symbol(< description >)
function returns an anonymous, unique value1
Symbol('foo') === Symbol('foo') // false
This functon has its static propertise and methods
1
2
3
4let sb = Symbol.for('foo')
let sb2= Symbol.for('foo') //saved the value in global env in the memory
sb ===sb2//true
Symbol.keyFor(sb) //'foo'Not
new Symbol()
❌1
let sym = new Symbol() // TypeError
1
2
3
4let sym = Symbol('foo')
typeof sym // "symbol"
let symObj = Object(sym)
typeof symObj // "object"But it has instance/prototype properties and methods
1
2
3Symbol.prototype.toString()
let sb = Symbol('context');
console.log(sb.description); //contextReturns a string containing the description of the Symbol. Overrides the Object.prototype.toString() method.
Use cases
To dealing with the same string name, use symbol to create unique value;
1 | let user1= { |
inheritance
2020-06-12Inheritance of Object in JS
Disclaimer
This article is originally based on my understanding of this concept. No guarantee on the accuracy.😅
Prototype chain
Let subType’s prototype points to an instance of the superType;
1 | SubType.prototype= new SuperType() |
Problems:
- The instance property of SuperType becoms the shared prototype property for SubType
- There is no way to pass arguments to the constructor of superType
Constructor stealing
Calling the constructor of supertype inside the constructor of subtype.
1 | function SubType(...arg){ |
Problems:
- No access for Subtype to the prototype method/properties of the SuperType
- The methods are defined inside the constructor which makes them instance method. Not shared with all instances;
Combination inheritance
Prototype chain + constructor stealing
1 | function SubType (..args){ |
Problems:
- The constructor function always be called twice during the inheritance;
Prototypal inheritance
The constructor is not necessary to perform inheritance. It simply can be done by a object itself.
1 | Object.create() |
Inheritance using constructor:
1 | SubType = Object(SuperType.prototype) |
Parasitic inheritance
Create a function only focus on encapsulation
1 | function parasitic(prototype){ |
Problems:
- The methods are not shared with instances;
Parasitic combination
For combination inheritance, the constructor function was called twice.
The instance property of superType were created first to be the prototype property of subtype, (SubType.prototype = new Super())
then created as iinstance properties.(inside the constructor)
1 | function inheritance(subType,superType){ |
Mixing inheritance
JS dosen’t support multiple inheritance, but method of different class/object can be borrowed by mixing
1 | let Student ={ |
browser rendering
2020-06-08Browser rendering
Disclaimer
This article is originally based on my understanding of this concept. No guarantee on the accuracy.😅
Few key points:
- The parsing and creation of DOM tree and CSSOM tree is independent.
- The render tree can only be created when both CSSOM and DOM tree are ready.
The sync < script > tag would block the building of DOM tree, because:
- the Javscript has to wait the CSSOM tree to be built since it may need to manuplate or get information about the sytle. And the DOM tree has to stopped since it not sure if the js would interact with the DOM tree.
- So the CSSOM tree keeps building. When the CSSDOM tree finishes, the browser starts to parse js and execute it.
- If the script is trying to manipulate any dom element that hasn’t be created, it would fail. So normally the script tag was put at the end of the body tag.
- Then the DOM tree re-start to build.
- The mordern browser allows the rendering to perform bits by bits.
![browser rendering-Page-2](browser-rendering/browser rendering-Page-2.png)
To shorten the time before the first-screen-rendering, it’s better to make the scirpt tag
async
Now the parsing of CSS and html can again performs parallelly.