- 1. CMD
- 2. NPM
- 3. the principle of component design
- 4. browser rendering
- 5. html
- 6. SVG
- 7. CSS
- 8. Storage
- 9. RegExp (regular expressions)
- 10. Javascript
- 10.1. symbol and keyword
- 10.2. Data Types
- 10.3. variable declaration
- 10.4. Object
- 10.5. Array
- 10.6. scope
- 10.7. garbage collection
- 10.8. prototype
- 10.9. differ between vue and react
- 10.10. Architectures
- 10.11. closure
- 10.12. deep and shallow copy
- 10.13. event loop
- 10.14. debounce and throttle
- 10.15. breakpoint resume
- 10.16. messageChannel
- 10.17. generator
- 11. Typescript
- 12. React
- 13. web3
- 14. webpack
- 15. HTTP
- 16. Vscode
- 17. terms
CMD
cmd
keyword | function |
---|---|
mkdir data | file creating |
start . | open a given file |
mklink <path + link name> |
soft link |
cls | to clean screen |
sysdm.cpl | open system propety |
cleanmgr | to clean disk |
ipconfig/all | ip address checking |
&& | to adjoin multiple command |
taskkill /im ffmpeg.exe /f | to stop a processor |
taskkill /pid 1812 /f | to stop a processor |
tasklist | to check processor list |
npm
keyword | function |
---|---|
npm install -g npm | npm updating |
npm list -g –depth 0 | to check global package |
yarn upgrade | to update all the dependencies listed in the package.json |
NPM
1 | npm version patch // v1.0.1 |
- to control the files of a package
- define the
file
field in thepackage.json
- use
.npmignore
which is used same asgitignore
- define the
the principle of component design
- single responsibility principle. to compose complex components by smaller specialized components.
- conceal the construction of a conpoment, and only reveal the necessary information
- awalys return same ouput for given same input, so they are predictable, and determined
- keep loose coupling, not tight coupling. having little or no knowledge about other components.
- composable. Composition is a way to combine components to create a bigger (composed)
- reuseable
- pure or almost pure function, and no side effect which means haven’t depending on environment or global state, like network or global variable
- isolate the impurecode from the pure
- straightforward to test
- a meaningful name. a component is more special, so its name might contain more words, like
<HeaderMenu>``<Header>
a grade on usage about judging a component’s level
1. Reading name and props; best
2. Consulting documentation; good
3. Exploring the code; admissible
4. Asking the author. avoid
browser rendering
the rendering process
- browser take the IP address of domain name by means of DNS(domain name system) analysis,like juejin.im 对应的 IP 是36.248.217.149
- sending http request to the IP address
- server take the request and return html content
- browser get html string
- analyze html => dom tree
- analyze CSS => CSS rule tress
- after the analysis process => start to structure the rendering tree(only contain those nodes which need to display)
GUI rendering thread and JS engine thread
GUI(graphical user interface) rendering thread and JS engine thread are mutual exclusive. download, analysis and execute of JS will stop the rendering process. in other words, when JS is encountered, the rendering process will stop to structure the rendering tree and transfer the control right to JS engine.
reflow and repaint
- reflow: the change of DOM geometrical size(like width, height, or display) will affect the layout of page or the position of other element
- repaint: when the style(like color, background) of dom changed
if repaint didn’t affect dom geometrical size, then reflow is not necessary, but reflow will incur repaint definitely.
to avid reflow and repaint as much as possibile
- use
transform
instead ofpositive and top
- use
visibility
instead ofdisplay:none
, the former will incur repaint while the latter will change layout - to avoid getting the property value of elements as much as possible, because getting the value of offsetTop will incur reflow
html
img responsive
1 | <picture> |
get size and position of an element
SVG
properties
width/height: define the size in the document
viewBox: first two number are min-x and min-y used to define the position, the other two are define the scale relative to width/height
1 | when the viewBox is same as width/height, then the dimension is 1. if it is smaller than width/height, then the dimension is larger than 1, and vice versa. |
path
M: move to
L: line to
H: draw a horizontal line
V: draw a vertical line
Z: close path, combine the start and the end
C: curve, x1 y1 x2 y2 x y, the last set x y specify where the line should end and the line start at the point where the last operation ended, the first two are control points.
1
2
3
4<svg className="selected-roundbtm" viewBox="0 0 8 8" width="8" height="8" xmlns="http://www.w3.org/2000/svg">
<path d="M 0,8 L 8,8 L 8,0 C 8,0 8,8 0,8 " fill="#fff"></path>
<circle cx="0" cy="0" r="8" stroke="#e4e4e4" fill="none" />
</svg>
S: smooth curveto
A: rx ry x-axis-rotation large-arc-flag sweep-flag x y
, this one drawing a arc of a circle or ellipse
rx ry
radius x and radius ylarge-arc-flag
determains that the arc should be greater than or less than 180 degrees.sweep-flag
determains that the drawing direction is clockwise or anticlockwise.x y
the ending point calculated with angle, while the arc starting point is at three o’clock of a circle,circle center + radius = the arc starting point
1
2
3
4
5
6
7
8// get the ending point with an angle
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees * Math.PI) / 180.0 // the length of the arc
var x = centerX + radius * Math.cos(angleInRadians)
var y = centerY + radius * Math.sin(angleInRadians)
return [x, y]
}
polarToCartesian(9,9,9,45)
Q: x1 y1, x y, quadratic Bézier curve, to control the slope of two sides with one point, which is the first set
T: x y, smooth quadratic Bézier curveto, auto control the slope of two sides according to the last control point
filter
in && in2, SourceGraphic | SourceAlpha | BackgroundImage | BackgroundAlpha | FillPaint | StrokePaint |
1.in
is the first input, andin2
is the second input, while the placing order is same with the layer order of PS
2.ifin
is not existed, then the value will be the previous filter input
- feBlend, to blend two layers ruled by a certain blending mode
in
in2
mode
- feComposite, to combine two input images
in
in2
operator
, compositing operations
CSS
useful properties
text-indent
retract the first line of a paragraph,and not working with </br>
backwards
在 animation-delay 所指定的一段时间内,在动画显示之前,应用开始属性值(在第一个关键帧中定义)。
both
向前和向后填充模式都被应用。
打印的每页带有表头: 包裹tr 标签, 让打印的每一页都带有表头
1 | <thead style="display:table-header-group"></thead> |
width setting
1 | { |
background
1 | /* |
-webkit-box-reflect: right;
reflect
vertical center
1 | { |
ellipsis is used for one line
1 | .single { |
ellipsis is used for multiple lines
after 伪类 + 定位
position:sticky
当元素在屏幕内,表现为relative,当要滚出显示器屏幕的时候,表现为fixed
attr()
1 | /* get data with attr(), and needless for joining text with +*/ |
1 | <div class="test" data-text="TEXT" data-color="red"></div> |
1 | htmlelement.dataset.text = “content” |
shape-outside
make the adjoining inline-elements around itself
CSS variable
1 | :root { /* defining,it is not necessary to place in root*/ |
1 | var root = getComputedStyle(document.documentElement); // accessing |
pseudo-class
:before
and:after
are used to add elements, also float cleaning, and cannot used with img/select/input:enabled
and:disabled
are used for customizing style of form according to status:checked
when checkbox or radio are choosen
selector
pseudo-class-selector
1 | p:first-of-type { } |
other
1 | /* the p after h1 is selected */ |
unit
vw / vh / px
vmin / vmax
1% of viewport’s smaller/larger dimension.em
relative to the parent’s font-size, not bodyrem
relative to Html elementfr
represents a fraction of the available space in the grid container
1 | /* 16px(default size) === 1rem 公式16px*62.5%=10px */ |
lh / rlh
Line height of the element / the root element..ex
x-height of element’s heightcap
the normal height of capital lettersch / ic
average Average character advance of a full width glyph in the element’s font
grid
properties
grid-template-columns
grid-template-rows
grid-auto-clumns
grid-auto-rows
grid-colum-start
grid-colum-end
functions
repeat()
1
2
3
4{
grid-template-columns: 20px repeat(6, 1fr) 20px;
grid-template-columns: repeat(5, 1fr 2fr);
}minmax()
, accept two params, the minimum and the maximum1
2
3{
grid-auto-rows: minmax(100px, auto);
}
performance optimization
- to avid
reflow
andrepaint
as much as possibile - use
prefetch
andpreload
to define the executing order of js, in order to avid blocking html rendering.
CSS-layout
basic
自适应: 多套代码根据用户代理提供不同版本的网页,在不同大小的设备上,网页以等比例的形式缩放宽度,呈现同样的主体内容和排版布局
响应式: 一套代码,通过流式布局+弹性布局调整网页
物理像素:计算机硬件,真实屏幕的像素点
css像素:属于逻辑像素的一种
设备像素比(Device Pixel Ratio,DPR):物理像素与逻辑像素之比吗,比如iphone6物理像素是750*1334,但实际逻辑像素是 375 * 667,所以dpr = 2,这表示iphone6采用高清屏使用两个像素去渲染一个像素使画面更高清,iphone6 plus 甚至是dpr = 3
1px 问题:设计师的视觉稿是相对于物理像素750px,实现一个1px边框,但css逻辑像素是375px,border-width:0.5px 使用transform: scale(0.5)
% + meta
vw/vh/% + px + flex layout,响应式布局
flex + vw/v/%h布局,局部使用px
在跨设备类型的时候(pc <-> 手机 <-> 平板)使用媒体查询
rem ,响应式布局,动态设置root的fontsize,子节点使用rem,和flexible不同的是可以根据pc、手机、平板的尺寸来设置比例使子节点计算方便
1 | var deviceWidth = document.documentElement.clientWidth |
flexible, self-adoption
- 模拟vw特性,动态的将页面宽度的1/10作为根节点的fontsize,子节点使用rem就等于是按照页面比例计算
1 | var doc = document.documentElement |
2.高倍屏适配,修改了等比缩放视口的scale值,使得clientWidth变为物理像素尺寸,1物理像素等于1css像素,由原来的375=>750, media尺寸查询语句也同样需要修改
1 | var metaEL = doc.querySelector('meta[name="viewport"]') |
Storage
cookie
, 4kb, can set the expire time,httpOnly = true
means this cookie is server setting and only can be changed by server1
2
3document.cookie = "yummy_cookie=choco"
document.cookie = "tasty_cookie=strawberry"
console.log(document.cookie)localStorage
sessionStorage
, 5MB1
2
3
4localStorage.setItem('chooseId',JSON.stringify(this.$route.params))
localStorage.removeItem('chooseId')
localStorage.clear()
localStorage.key(index)indexedDB
no size limits, it can do everying a database doescaches
, an object which includecache instance
s, eachcache instance
can viewed as a storge region. the return type of all the methods ofcaches
orcache instance
are promise.- methods which are mounted on
caches
are used for managingcache instance
s.caches
:keys
open
delete
has
match
- differ between
has
and match: has return booean while match give you the data
- if we want to store something, then we need to use
open
to get acache instance
where is our data staycache
instance:add
addAll
keys
delete
match
matchAll
put
1
2
3
4
5
6
7
8// differ between `add` and `put`: add can `fetch` and `store` the data automatically, but also because of automatically then we can't make changs on key and value to be stored
// so fetch + put = add
cache.add(request).then(function() {
// request has been added to the cache
});
fetch(url).then(function(response) {
return cache.put(url, response);
})- when use
cache with severice worker
, the data we stored is the rawresponse
data returned byhttp
- methods which are mounted on
RegExp (regular expressions)
1 | var re = new RegExp(“a”, "img"); // a RegExp object |
PS Safari does not support the previous four expressions
modifer
i
ingnore uppercase and lowercase of lettersg
global matching, to search from the start to the end whatever how muchm
matching on multiple lines- es6
u
turn onUnicode mode
to deal with Unicde characters - es6
y
similar withg
, but it’s match work started form the beginning of the string- it’s effect is equal to add
^
at the beginning of a regexp, so it could regarded as a complement for thatg
couldn’t add^
sticky
, new property of RegExp, to know the regexp is addedy
or not
- it’s effect is equal to add
Properties
es6
regexp.flags
, get all the modiferses6
regexp.source
, get the regexp contextregexp.lastIndex
, allow you to define and get the index from where the next match work started1
2
3
4
5const REGEX = /a/g;
REGEX.lastIndex = 2; // to define the index
const match = REGEX.exec('xaya');
match.index // 3
REGEX.lastIndex // 4, to get the index
test(), is matching or not
1 | regExp.test(str) // boolean |
search()
1 | string.search(regExp) // return an index or -1 |
replace(), es6 replaceAll
1 | string.replace(regExp, replaceText) // return the replaced string |
exec()
1 | regExp.exec(string) // return an array of information which include lastIndex, allow you to match along the last position. |
1 | // use with while |
with named capture groups(具名组匹配), you can get the data of each group which declared by ()
1 | const regExp = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ |
match(), es6 matchAll
1 | 'For more information, see Chapter 3.4.5.1'.match( /see (chapter \d+(\.\d)*)/i) // return an array of information |
symbols
key | usage |
---|---|
() |
Parentheses, to group regular expressions |
[] |
match any character within the brackets |
^ $ |
match from the start or the end of the string |
[^a] |
match string which no ”a“ |
{n,m} |
the display times > n and < m |
{n,} |
the display times > n |
{,m} |
the display times < m |
* |
equal to {0,} |
+ |
equal to {1,} |
? |
equal to {,1}, /.*?(\d)/, when ? is uesd with greed mode, it means to exclude a specific format |
` | ` |
. |
equal to {1,} |
/d |
equal to [0-9] |
/D |
equal to [^0-9] |
/w |
equal to [a-zA-Z_] |
/W |
equal to [^/w] |
/s |
equal to [ \f\n\r\t\v] (换页,enter,空格,tab,垂直制表符) , matching all the empty chacaters |
/S |
equal to [^/s] |
/S/s |
all the characters |
(. | \n)* |
?=n |
match string but don’t get, the string after which is n |
?!=n |
match string but don’t get, the string after which isn’t n |
?<=n |
(uncompitible with safari) match string but don’t get, the string before which is n |
?<!=n |
match string but don’t get, the string before which isn’t n |
?:n |
match string but don’t get |
examples
to match a string, stop matching until a specific format is encountered
1
'"/public/images/index/组 4099.png","textAlign":"'.match(/public\/images\/(.*?(?="))/img)
verify float number, which has two standards and judged by “|”symbol
1 | /^(([0-9]+\.?[0-9]+)|([0-9]*))$/.test("5.") |
- get a array of date number arranged by
[year, month, day, hour, minute, second]
1 |
|
- extract the type in the string returned by
Object.prototype.toString.call
1 | /(?<=\[object ).*(?=])/.exec(Object.prototype.toString.call({})) |
- remove a special pattern at the start and end of a string
1 | '""yyy"'.replace(/^"?|"?$/g, '') |
Javascript
symbol and keyword
keyword | function |
---|---|
=~ |
按位非var num1=~25;//-26 值反一次再减一 |
Math.sqrt | 根运算Math.sqrt(100) // 10 |
6%4 |
取余, c%2 !== 0 |
~~ |
取整 ~~(6 / 4) // 1 ~~(9 / 4) // 2 |
&& |
逻辑与 |
` | |
! |
逻辑非 |
!! |
反了之后再反一次 |
yield next yield* |
to stop or resum a generate function, yield* 加入另一个可迭代的对象 |
es6 ?. |
optional chain, stop running when null or undefined is encountered |
es6 ?? |
null ?? 4; 4 ?? 5 the right value will be returned when the left value is null or undefined |
es6 ` | |
es6 &&= |
a &&= 1 === a && (a=1) // if a is existed then assign 1 to it |
es6 ??= |
a ??= 1 === a ?? (a=1) // if a is null or undefined then assign 1 to it |
es6 ** |
指数运算符 2 ** 3 // 8 b **= 3; // equal to b = b * b * b; |
es6 symbol |
data type:desiged to prevent the conflicts of property name |
delete obj.a
delete an object’s own property but not those properties which is on the object’s prototype chin, and returnboolean
in
: used to know whether a property existes in aobject/array
1
2var arr = [1]; console.log(0 in arr); // true
var arr = { a: 4 }; console.log('a' in arr); // truees6
…
spread syntax: to expand an iterable such as an array expression or string1
2
3
4
5
6
7
8
9// express rest arguments
const bar = (...args) => args
// to concate or insert items in an array/object
{ ...obj1, ...obj2 }
[...iterableObj, '4', 'five', 6]
// Applying with new operator
new Date(...[1970, 0, 1])while
, the expression inside brackets can be a assigning expression, the judge criterion is the value of the variable1
2
3
4
5
6var i = 1
while ((aa = i)) {
console.log(aa)
i++
if (i === 5) i = null
}break
continue
return
,break
is used inswitch/while/if/for
to break a layer of the loop, only one layer1
2
3
4for (let i = 0; i < 5; i++) {
if (i === 3) continue
console.log(i)
}es6
set
whose members are similar with Array, butset
will not have a repeated value1
2
3const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // the length is 5, and the repeated value aren't be counted
items.add(6) // add itemes6
map
is similar withset
, but the shape ofmap
members iskey: value
like object. except thekey
of anobject
is awalysstring
, while thekey
of amap
can be any type.1
2
3
4
5const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o)
m.size // 1es6
WeakMap && WeakSet
, all the properties of the two are shallow copied(weak reference), if anobject
are referenced only byWeakSet
, then thisobject
will be deleted by Garbage Collectionexport && import && export default
Data Types
undefind
null
variable declaration
var
- if a
var
variable is not declared in a function scope, then it is aglobal object
and is mounted onwindow
- can be re-declared in a same scope
1
2
3
4
5var b = 1
var b = 1
let c = 10
let c = 20 // Identifier 'b' has already been declared var
variables can be used before declare,var
declaration will be raising to the first line when engine is running, even a variable is declared in aif
block1
2
3
4console.log(a) // warning
let a = 1
console.log(b) // undefined
var b = 1
let, const
let
is used declare a variable.const
is for a constant whose assignment and declaration are simultaneously. value cannot be re-assigned. for a reference type data, value just keeps the momery location unchanged.- block scope,no variable increase
1 | if (true) { |
- can’t used to declare a variable which’s name same as function’s arguments
1 | (function func(arg) { var arg })() |
Object
es6 shorthand
1 | const a = { |
iterate
for...in...
iterate object’s key and array’s indexforEach
can’t jump out byreturn
,forEach
for...of...
iterate value and can’t be used on Object
1 | Object.keys(obj) // obj's attribute names except Symbol, inherented and non-enumerable attributes |
Instance’s Properties
1 | obj.hasOwnProperty() |
Object’s Properties
- es6
Object.values({})
Object.keys({})
- es6
Object.assign()
, copy the properties of the arguments to the first argument - es6
Object.entries({})
Object.fromEntries([])
transform object to array and vice visa1
2
3const obj = {a: 'somestring', b: 42}
Object.entries(obj) // [['a', 'somestring'], ['b', 42]]
Object.fromEntries(Object.entries(obj)) // {a: 'somestring', b: 42} - es6
Object.is(value1, value2)
compare whether two values are same, can be used to compare objects by compareing they reference. almose same as===
, but there has two difference:1
2
3
4
5+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true Object.prototype.toString.call()
get data’s type- es6
Object.getOwnPropertyDescriptors
- es6
Object.setPrototypeOf()
Object.getPrototypeOf()
set and get the prototype of an object
JSON Object
eval(string)
can execut js codeJSON.parse(string)
JSON.stringify(obj)
obj.toJSONString()
Array
scope
scope types
global scope
- defined at the external of the outmost function
- if a variable is not declared by any keyword like
var
,let
andconst
- belonging to
window
ES6 Module scope
1 | // lib.js |
function or local scope
a variable is declared within a function, so it can’t be accessed from the outside.
block scope
if / switch / while / for
create a block scope. a variable which is defined by let / const
static scope
when looking a variable, the engine will go to the scope in which the variable was created
1 | var x = 10 |
nested scope
a scope can be nested inside another scope.
scope chain
when the JavaScript engine try to find a variable, first it will seek in the current scope, if there is no result then it will go to the parent’s scope. finding layer by layer, that is scope chain.
1 | var a = 100 |
garbage collection
FinalizationRegistry
to registe an obj and invoke a callback after the obj is garbage-collected
1 | const registry = new FinalizationRegistry(heldValue => { |
Stale closure
The stale closure captures variables whose value is outdated
createIncrement
function returns two functions,increment
andlog
. The former responsible for value increasing. the latter logs aconst
, whose value is fixed since it defined, then every time call thelog
fun, it getsmessage
which is a fixed value.
1 | function createIncrement(incBy) { |
- when use setTimeOut and setInterval, in which the function delay to execute, but every variable that the fun got is the current value at the time of the fun defined, that is to say if the variables get changed during the delay time, then the fun only get the old variables.
prototype
every object has a
prototype
, from which the object can inherit properties and methodsan instance inherits
prototype
fromconstructor
, which is placed on the__proto__
a
constructor
has aprototype
which has two propertiesconstructor
and__proto__
, besides it has proto property which is inherited fromObject.prototype
- the former, the prototype.constructor refer to the default constructor
- the latter, even all the built-in functions such as Object, Function, Array、RegExp、Date、Boolean、Number、String , the prototype.proto of them point to the Object.prototype, that means they inherited from Object, and Object.prototype.proto refer to null.
1 | Person.prototype.constructor === Person // Person is a constructor, Person.prototype.constructor point to the "constructor" function self |
property chain
when we access the property
of an object, first the engine will try to find the property
in the object, if it doesn’t find, then it will look at the object.__proto__
, if it still doesn’t find , then look at the object.__proto__.__proto__
,…. at the end of the prototype
chain of __proto__
, the engine will find the Object.prototype
, in which the prototype
is null, then the engine will be sure that the property
doesn’t exist.
diff between constructor and normal function
- a
constructor
usually doesn’t usereturn
keyword, becausethis
of aconstructor
will be used as the result ofnew
keyword. - when the returned result from a
constructor
is an Object, then the result will be used as the result returned by new keyword. otherwise, if the result is primitive type, thenthis
will be as the result of new keyword. - by the first rule,
this
andnew
are used in a constructor but not in a normal function
what does NEW do?
- create an Object
- bind
this
of the current scope to the object - copy the prototype from the constructor, and placed it in the
object._proto_
- execute the code inside the constructor, and return the object
Inheritance
- create a child object classes which will inherit features from another class
- OO => object oriented programming
- favor object composition over inheritance
- concatenative inheritance, inherit features from another object by copying the source objects properties
- Object.assign()
- … spread syntax
- bind, call and apply(can receive an array). binding “this” to a function
1 | let bebound = { a: 1 } |
prototype delegation
new
constroctor- functional inheritance / factory function. it is not a constuctor or class. it works by producing an object from a factory, and extending the produced object by assigning properties to it with concatenative inheritance.
- class extend / subclassing.
inherit everything from a class, can’t choose what you wanted
this initialization by calling the parent’s constructor with super() and can pass arguments to the parent, while in the contructor function that the new keyword does the initialization automatically.
differ between vue and react
- Vue
- focus on view, that made dom operations more flexible and productivie
- when you have some public functions, you cann’t import those function in template tag, you also have to write script tag
- React
- more suitable in a complex project
- to render html by jsx
- below diffs are also the diff between class component and function component
- no
this
issues in function components, you don’t have to do scope bonding, when you inherit someone’s code, if you don’t search, you dont’t even know whatthis
have - code lesser with function component, but worse maintaining
- doesn’t need to manage state and life cycle
Architectures
mvc
- Model - View - Controller
model
is not only contains data model, also describes how the data can be changed and manipulated.view
is the UI components which is rendered by the data from the controller.controller
sits betweenmodel
andview
, like a mediator processing the data from themodel
and passing back to theview
for rendering.- view and model can interact with each other directly, so it’s coupled.
mvvm
- Model – View – ViewModel
view
is same with theMVC's view
model
stores data and related logic, rec- like mvc,
ViewModel
sits between model and view. but it accepts user’s data fromview
and the data from model, and interacts withview
andmodel
. view
andmodel
can’t interact with each other, it’s decoupled.
mvp
- model - view - presenter
- mvp is derived from
mvc
. it’s decoupled, means view and model cann’t talk to each other.
active view and passive view
- the later only outputs UI and doesn’t accept user’s input, contains zero logic
- the former contains events, data binging, and behaviors
closure
closure is a combination created by binding a function to the lexical environment. it allow you to access the outside scope from the inner of the function.
data privacy
. it means that you can’t access the data of the inner scope from the outside.privileged methods
. the methods exposed by the function are privileged, because they still have right to access the arguments of the inner scopestateful function
. a state is a snapshot of the current environment, every change will take a picture of the current environment.
1 | var func = () => { |
partial application
. it takes advantage of closure scope in order to fix parameters.
1 | const partialApply = (fn, ...fixedArgs) => { |
deep and shallow copy
basic data type: data is stored in the
stack
reference data type: data is stored in the
heap
, while thestack
only have object’s referenceshallow copy: only copy the reference
deep copy: copy data
the following methods can deep copy but only the first layer of an object.
1 | Object.assign({}, state) |
completely deep copy
JSON.parse(JSON.stringify())
, some complex types will be translated into string:Dates
,functions
,undefined
,Infinity
,RegExps
,Maps
,Sets
,Blobs
,FileLists
,ImageDatas
,sparse Arrays
,Typed Arrays
undefind
will be ignored- can’t convert an object in which some properties are refer to each other
1
2
3
4
5
6
7
8
9
10
11
12let obj = {
a: 1,
b: {
c: 2,
d: 3,
},
f: undefined
}
obj.c = obj.b;
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
MessageChannel
, the dataMessageChannel
delivered is deep copied. when comparing toJSON
, only one shortcoming, just can’t deliver a function will cause an error1
2
3
4
5
6
7
8
9
10
11function deepCopy(obj) {
return new Promise((resolve) => {
const { port1, port2 } = new MessageChannel()
port2.onmessage = (ev) => resolve(ev.data)
port1.postMessage(obj)
})
}
deepCopy(obj).then((copy) => {
console.log(copy);
})
event loop
Heap and Stack?
- the former is where objects in, the latter in where the functions are waiting to execute.
synchronous and asynchronous
- they are two kinds of js tasks. the former constitutes an
execution context stack(执行栈)
in theMain-Thread
, the latter in theTask Queue
.
- they are two kinds of js tasks. the former constitutes an
what is Event Loop?
- after all the tasks of
Task Queue
are done, the engine will constantly readingtask queue
and trying to find tasks in which the waiting status can be end. once it find, the engine will push it intostack
. the process that JavaScript engine constantly finding tasks is calledEvent Loop
.
- after all the tasks of
Call Stack
- every call of function will leave a
Call Frame(调用帧)
, which keeps the inner information about function including variables and the location where the function called, those information will be deleted after the function is completed.1
2
3
4
5// put C into stack => B in => A in => A out => B out => C out
function funA() { console.log('funA') };
function funB() { funA() }
function funC() { funB() }
funC()
- every call of function will leave a
Task queue
have been divided into two typesMacro
andMicro
- the former including
setImmediate
/setTimeout
/setInterval
/MessageChannel
/requestAnimationFrame
/UI render
/I/O in node.js
, while the later including theonerror
andthen callback of Promise
. - setImmediate -> MessageChannel -> setTimeout 0
- usually the engine will check the
MacroTask
first and theMicroTask
second. however, there has an important point thatPromise initialize and resolve are synchronous
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20setTimeout(function () {
console.log(1)
}, 0)
var p1 = new Promise(function (resolve, reject) {
console.log(2)
setTimeout(function () {
console.log(4)
resolve(1)
}, 0)
})
setTimeout(function () {
console.log(3)
}, 0)
for (var i = 0; i < 5; i++) {
;(function (j) {
p1.then(function (value) {
console.log("promise then - " + j)
})
})(i)
}
- the former including
async
await
, look at the following example:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20async function async1(){
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
},0)
async1();
new Promise(function(resolve){
console.log('promise1')
resolve();
}).then(function(){
console.log('promise2')
})
console.log('script end')async1()
dosen’t haveawait
prefix,async1
will be translated by v8 like:1
2
3
4
5
6
7// async2 will execute immediately, the code after `async` will be put in `then` callback
function async1(){
console.log('async1 start')
Promise.resolve(async2).then(()=>{
console.log('async1 end')
})
}
Tail Call
means to call another function at the end of a function’s operation.1
function a(x) { return b(x) }
b
is aTail Call
. fromCall Stack
, we know that the fun will keeps it’s inner info unitl its operation is complated. whileTail Call
is the final step of fun, the fun is completed after calledTail Call
, then theCall Frame
of fun is no longer keeped.- this will save a great memory, also called
Tail call optimization
.
Tail Recursion
- at the reason of
call frame
, thatRecursion
often takes a lot of momery and causestack overflow
, for optiomization we can useTail Recursion
.1
2
3
4
5
6
7
8function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
function factorial(n, total) {
if (n === 1) return total;
return factorial(n - 1, n * total);
}
- at the reason of
debounce and throttle
debounce. a function can be executed when it is not called during a specific time
1
2
3
4
5
6
7
8
9
10
11// execute debounce => got a function which bound with the debounce scope
// every time the instance exectuted that will clean and reassign the timer
const debounce = (func, delay) => {
let timer
return function () {
const context = this, args = arguments
clearTimeout(timer) // to clean before reassign
timer = setTimeout(() => func.apply(context, args), delay)
}
}
const instance = debounce(function () { console.log("executing") }, 3000)throttle. a function can be excuted only when the time is up
1
2
3
4
5
6
7
8
9
10
11
12
13
14// execute throttle => got a function which bound with the throttle scope
//when the isexpiered is true, that means that the function can be executed and when it executed, then change the isexpiered's state to false and set a time to change back
const throttle = (func, delay) => {
let isexpiered = true
return function () {
const context = this
const args = arguments
if (isexpiered === false) return
func.apply(context, args)
isexpiered = false
setTimeout(() => isexpiered = true, delay)
}
}
const instance = throttle(function () { console.log("executing") }, 3000)
breakpoint resume
web: fileReader + slice + FormData
server: createWriteStream + createReadStream
messageChannel
- to communicate between two
iframes
/web workers
/js modules
- deep copy
generator
- use
generator
to simulate async function
1 | function run(fn: any) { |
Typescript
references
setting tsconfig for specific file
diff with js
pro:
- object-orient language
- static type checking. it can find low level bugs while coding, like spelling mistake, incorrect or unexist variable properties
- optional parameters
- enum support
- better ide support, intelliSense in editor, auto-supplement
- the type files can increase code reading, and make the project easly maintaining
.d.ts
can be viewed as specifications- to identify incompatible interfaces when the field name changed
con
- compiling step is requied, and it may need long time.
- not suppoty abstract classes
- definition file is required when use a third library
type judgement
Generics
keyof
typeof
indexed access:
User["name]
map types, use
-
or+
to remove readonly or optional modifier1
2
3
4
5
6
7
8
9
10type OptionsFlags<Type> = {
[Property in keyof Type]: Type[Property]
}
// change all readonly or optional properties to normal
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
Diff of null
and undefind
null
means an absence of valueundefined
means the variable are not initializated
Diff of .ts
and .d.ts
.d.ts
file is a declaration file, and would not be complied as ajs
file- in a
.d.ts
file, if we want it act as a global declaration, then we have to use/// Triple-Slash Directives
to replaceimport
for import dependences /// <reference types="node" />
is used for importing an outside module, while/// <reference types="./global.d.ts" />
is for importing a localdeclaration
file
- in a
Diff of type
and interface
type
is used to declare a type alias, it is act like a variable. while interface introduce a named object type.1
2
3// get the type of a variable to deduct (a part) of a payment from (the total)
let div = document.createElement("div")
type B = typeof divExtends
, that the both can extends from another, no matter the parent istype
orinterface
1
2
3
4interface User extends Name {
age: number;
}
type User = Name & { age: number }- Adding new fields to an existing interface, but a type cannot be changed after being created
1
2
3
4
5
6
7
8interface User {
name: string;
age: number;
}
interface User {
sex: string;
}
/* { name: string; age: number; sex: string } */
features
new
describe the shape of a constructorabstract
to mark a class withabstract
, means that the class is only meant to be extended from, can’t be used directly1
2
3
4
5
6
7
8
9
10abstract class Shape {
abstract getArea(): number;
}
new Shape(); // error Cannot create an instance of an abstract class.
class Square extends Shape {}
new Square(3) // rightextends
SomeType extends OtherType ? TrueType : FalseType;
1
2
3// if Dog extends from Animal, then Example1 = number, otherwise Example1 = string
type Example1 = Dog extends Animal ? number : string;infer
can be used to unpack type, to get the item type of an array, the return value or parameters type of a function1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// if T is a function ? the return value of that function : any
type Unpack<T> = T extends (...args: any[]) => infer R ? R : any;
// if T is an Array ? R : T
type Unpack<T> = T extends Array<infer R> ? R : T
// if R is Reducer ? Reducer's first parameter S : never
type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any> ? S : never;
type Reducer<S, A> = (prevState: S, action: A) => S;
// get the parameter type of a constractor
abstract class AbstractClass {
constructor(a: string, b: number) { }
}
export type InferAbstract<T> = T extends abstract new (...args: infer Args) => infer _ ? Args : never; // new a function which return a value, infer the parameter as Args, mark the value as abstract class, if T is a abstract class ? Args : never
type Result = InferAbstract<typeof AbstractClass> // [a: string, b: number]decorators, use the form
@expression
, where expression must evaluate to a function.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19function first() {
console.log("first(): factory evaluated");
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("first(): called");
};
}
function second() {
console.log("second(): factory evaluated");
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("second(): called");
};
}
class ExampleClass {
@first()
@second()
method() {}
}Record
1
2
3
4
5
6type AnyObject = Record<string, any>
type Coord = Record<"x" | "y", number>
type Coord = {
x: number,
y: number,
}Readonly
Partial
Required
: all the properties are Readonly or selectable or required1
2
3
4
5type Coord = Partial<Record<"x" | "y", number>>
type Coord = {
x?: number,
y?: number,
}Pick
omit
: to pick or omit some properties from a given type1
2
3type Coord = Record<"x" | "y", number>
type CoordX = Pick<Coord, "x">
type CoordX = Omit<Coord, "x">ReturnType
Parameters
, the former is used for getting the output of a function, while the later is used for a function’s input1
2let timer: ReturnType<typeof setTimeout>
Parameters<(props: Event) => void>typeof
1
2const zed: Hero = { name: "影流之主", skill: "影子" };
type LOL = typeof zed; // type LOL = Herokeyof
1
2
3
4
5
6interface Person { name: string; age: number; location: string; }
type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[]; // number | "length" | "push"|"concat" | ...
type K3 = keyof { [x: string]: Person }; // string | numberenums
1
2
3
4
5
6
7
8
9
10
11enum Themes {
default = "_default",
thinkuem = "_thinkuem",
safeuem = "_safeuem",
}
// collect all the values of a a enum
type ThemesVal = `${Themes}`
// collect all the keys of a enum
type ThemesVal = keyof typeof Themes
// generate a interface
type ThemesVal = Record<Themes, string>template literal type,a set of every possible string literal that could be represented by each union member
1
2
3type a = 1 | 2 | 3
type b = 4 | 5 | 6
type ab = `${a}_${b}` // "1_4" | "1_5" | "1_6" | "2_4" | "2_5" | "2_6" | "3_4" | "3_5" | "3_6"type asseration,
as
or<>
syntax1
2
3let value: unknown = "Foo";
let len: number = (value as string).length;
let len: number = (<string>value).length;is
1
2
3export function foo(arg: string): arg is MyType {
return ...
}in
1
console.log('model' in car); // boolean
this
1
2
3
4
5
6
7class Box<T> {
value?: T;
hasValue(): this is { value: T } {
return this.value !== undefined;
}
}as const
1
2
3
4
5
6let x = [0, 1] as const; // let x: [0,1]
// another write pattern: let x = <const>[0, 1];
let x = [0,1] // let x: number[]
let y = [10, 20] as const; // Type 'readonly [10, 20]'
let z = { text: "hello" } as const; // Type '{ readonly text: "hello" }'any
void
is used when a function’s output isnull
orundefined
, if a fun does not usereturn
keyword then its value isundefined
unknown
is a type-safe of any type. you can narrow downunknow
to any type by type assertion1
2let foo: unknown = "Akshay";
let bar: string = foo as string;never
is used when a function can’t end which means it can’t return a value even an undefined. to express an empty object1
2
3
4
5
6
7
8
9
10function login(data: LoginForm): void {}
function login(data: LoginForm): never {
while (true) {}
}
function login(data: LoginForm): never {
throw new Error("jkkj");
}
type Empty = Record<string, never>map types
, to generate a type According to a map object, and can be agenerics
1
2
3type OptionsFlags<Type> = {
[Property in keyof Type]: boolean;
};index access
for looking up a specific property of a type1
type Age = Person["age"]
generics
generate a type with a specific params1
2
3
4function identity<T>(arg: T): T {
return arg
}
let myIdentity: <Type>(arg: Type) => Type = identitytemplate literial types
, with four featuresUppercase
Lowercase
Capitalize
Uncapitalize
1
2
3type PropEventSource<Type> = {
on(eventName: `${string & keyof Type}Changed`, callback: (newValue: any) => void): void;
};conditional
types1
type a = C extends B ? TypeX : TypeY
implements
, to check that whether a class is satisifed the contract specified by one or above interfaces1
2
3
4
5
6
7
8
9interface Runnable {
run(): void;
}
class Job implements Runnable {
run() {
console.log("running the scheduled job!");
}
}triple slash directives, to introduce other files in the compiling process
1
/// <reference path="..." />
class modifers
- public
- protected: All the members of the class and its child classes can access them, But not the instance of the class.
- private: Only the members of the class can access them.
useful tricks
refert to React component
1
2new() => React.Component<any, any>
typeof React.Componentpromise type
, the arguments type of reslove is number, while the arguments type of reject is infer to any1
2
3
4
5
6
7
8
9
10
11function test(arg: string): Promise<number> {
return new Promise<number>((resolve, reject) => {
arg === "a" ? resolve(1) : reject("1");
});
}
- to overide a property of a interface extended
``` js
interface ColorPickerProps extends Omit<BasicProps<string>, "change"> {
change: import("react-color").ColorChangeHandler
}use
map
andliterial
to create new property names1
2
3type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};use
extends object
insteadofany
when reference to an object1
2
3function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {
return o[name]
}to extend html attributes
1
2
3
4
5declare module "react" {
interface DOMAttributes<T> {
name?: string
}
}
React
life cycle
Mount Stage
- initialize
- constructor
- inside the function
- before render
- getDerivedStateFromProps, have the new props and ready to change state
- inside the function to compare the state and then return what you want
1
2
3
4
5
6
7
8
9
10
11
12function ScrollView({row}) {
const [isScrollingDown, setIsScrollingDown] = useState(false);
const [prevRow, setPrevRow] = useState(null);
if (row !== prevRow) {
// Row 自上次渲染以来发生过改变。更新 isScrollingDown。
setIsScrollingDown(prevRow !== null && row > prevRow);
setPrevRow(row);
}
return `Scrolling down: ${isScrollingDown}`;
}
- render
- after render
- componentDidMount, http request should be send
- useEffect
- initialize
update stage
getDerivedStateFromProps
shouldComponentUpdate
- use useMemo to shallowly compare
1
2
3const Button = React.memo((props) => {
// 你的组件
});render
getSnapshotBeforeUpdate(1.contain state before update and after update,2.used to comparative calculations,3. in the end, it could return a value as the third argument of - DidUpdate)
- for getting the old and new state, by
useRef
- for getting the old and new state, by
componentDidUpdate
unmount stage
componentWillUnmount
- the return function of
useEffect()
change view
- setState() of class component
- even an empty object like
this.setState({})
will also trigger a new update cycle - not a async method
- when we call a
setState
, the data will not update immediatly, that becausa multipe call ofsetState
will be merged to one call. we can use callback to get the updated data. - we can use
setTimeout
or native events to step over React setting, to achieve a sync response.
- even an empty object like
1 | componentDidMount(){ |
useState()
useReducer()
hook of function componentcontext
, this is shallowly compare- use
ref
to change dom - forceUpdate(), only support in class component and it will skip
shouldComponentUpdate()
- dispatch() in redux
- native dom handlers
components conversation
- parent to chidren: props
- chidren to parent:callbacks inside the parent props
- between brother: find the common parent node, through the parent by the above methods
- cross layer: by context
- redux
Reconciliation algorithm
it is used to diff one tree with another to determine which parts need to be changed. also called
differ algorithm
key
when an array re-rendering, React will check each list item according to the last render. if an unexisted item of the last render is found in the current render, then react will create an new element. if an item of the last render is altered in the current render, then react will delete the old one and create a new one.
if we use index
as key
, the key will be changed as the array’s order changed
high order component
- HOC is a function, accepts a component and other arguments, return a new component which should keep similar interface with the original one.
- HOC’s name begins with
with
, likewithButton
1 | type HOC = (component: React.component, props) => React.component |
features
- it totally control the component, and add new features to it, like make the name of the data props.
- it can unify data scource, inform the component to change when the data of data-center change.
- it render different components based on status like after login, therefore it could avoid to set multiple routers.
- when a function needed in multiple components. a different way from importing the function in different components is to apply the function to > different components in HOC.
- if you want to change the component received in HOC, the better way is to return a composition of a new component and the component received, > rather than to change the component received directly.
- container and component. the former deals with data and props, the later receive props form container and only responsible for rendering.
Render Props
- it is a mode, a component with
a callback
which accepts component’s data and return React elements - tips: try not use
Render Props
withpureComponent
, becausethis callback
will return a new value after parent re-render. whilepureComponent
is shadow compare for reduce the times of children re-render, but withRender Props
the result of compare will awalys be false.
1 | <DataProvider render={data => ( |
render prop
is kind of a simplyHOC
1 | <Mouse render={mouse => <Component {...this.props} mouse={mouse} />}/> |
ref
info
- ref is a way for accessing dom
- create ref by
React.createRef()
anduseRef()
hook - it is not support to access
ref
directly on afunction component
which does not have ref instance.
callback ref
- differ from
React.createRef()
, pass a function to components is also allowed - a better way is use with
useCallback()
hook, then it wouldn’t be executed every time after component updated
1 | const inputRef = (node) => { |
ref forwarding
- Ref forwarding lets components opt into exposing any child component’s ref as their own.
- we can customize the data that the component exposes to the outside using
useImperativeHandle()
hook. - to access child node from a parent component for triggering focus or measuring the sise or position of a child dom.
- it is useful in High Order Component, like assigning ref to input’s ref in a input component
1 | function FancyInput(props, ref) { |
hook
- each component has an initial list of “memory cells”, when we call a hook like
useState()
, it reads the current cell or inializes it during the first render.- hook is a function which lets you to “hook into” React state and lifecycle features from function components.
- use pure function as much as possible, use the functions or effects that hooked in the component
a optimized tips
: when we need set an initial value returnd by a function in hooks, compare to give the fun as arguments directly to hooks, a more opimized write pattern is to set an arrow function in which to return the function.
1 | // fun will only execute once when the component initialize |
useState() keep local state in a function component, when we update a state variable, react replaces the state instead of merging it like
this.state()
in class component.useReducer() an alternative of
useState
is used to store a complicated state, like a small redux in a component.a best solution for passing callbacks to children is to use
useContext()
together withuseReducer()
. with this, we don’t have to pass callbacks layer by layer.- create a context object for passing
dispatch
to children, so any child within the component can get thedispatch
byuseContext
.
- create a context object for passing
useRef() it is used to store variables, and the value returned by it will be valid in the whole life cycle
useEffect() and useLayoutEffect() the former invoked after the data id updated, while the later is called after the DOM is updated
1 | useEffect(() => { |
- useContext() accept a context object created by
createContext()
and returns the current context value.. it’s used when components of different nesting levels need to access the same data.
1 | const value = useContext(MyContext) |
- createContext() accept a default value and returned a context object which has three properties. context will shallowly comapre the properities of value to decide whether it should re-render.
1 | const MyContext = React.createContext(defaultValue) |
provider
: a react component, that allows to consume components to subscribe to context changes.consumer
: a react component, that allows components to subscribe to context valuedisplayName
: can be modifed directly, and is showed in DevToolscontextType
: a property on a class component can be assigned a Context object
1 | < MyContext.Provider value = {/* some value */ } /> |
- useCallback() and useMemo() accept a function and an array of dependencies, the received function will be executed when any of the dependencies change. the former is used to memorize the received function, while the latter is used to memorize the value returned by the received function
useCallback()
allows you keep same callback after re-render. this method is recommend to use ascallback ref
to get node after mound
1 | const measuredRef = useCallback(node => { |
difference between class and hook
- class component is hard to reconstruct and decompose
- compilation of class component will generate a lot of auxiliary functions
- class component require
this
when passing a function to a component
1 | // by a arrow-function. when the parent refesh, a new arrow function will be generated and the offspring will refresh, even the received props haven't change |
redux
concept
1 | A(change) --> B(send an `action` to `store`) --> C(`store` dispatch the action to a `reducer`) --> D(the `reducer` return a new state to `store`) --> E(`state` changed) --> G(execute `listeners`) |
store a container created by
createStore()
, where data is changed and saved.state an object, your data
action an object, include a
type
property required and other properties. the kinds oftype
decide how many actions that a store have.reducer a function, receive an action ,and return a new state instead of change the present state. automatically triggered by store.dispatch()
- Reducers should be as the parameter pass to the
createStore()
when initalize the store.
- Reducers should be as the parameter pass to the
to
view
when state change
- changed by props with
dispatch
, this.props.dispatch({ type: ‘xxx’ }) - use this.setState() and store.getState() in use store.subscribe(), that used in the component
Redux Methods
createStore()
,reducers
as parameter is required, an initial state if you need, the third argument is enhancer like middlewareprovider
allow the redux hooks and connect to componentsstore.getState()
get the present statestore.dispatch()
sending an action to reducerstore.replaceReducer()
Replaces the reducer currently used by the store.combineReducers()
organize your reducers to manage their own slices of state. accept an object whose values are different reducing functions and turn it into a single reducing function you can pass tocreateStore
.1
combineReducers({ todos: myTodosReducer, counter: myCounterReducer })
bindActionCreators
is wrap action into dispatch1
2
3type actionCreator = (payLoad: any) => {...{type: string }, ...payload}
type dispatchAction = (payLoad: any) => dispatch(actionCreator(payLoad))
(actionCreators: actionCreator | actionCreator[], dispatch: Function) => dispatchAction | dispatchAction[]store.subscribe()
receives an listeners function and return a function in which you can disengage the listener.connect
return a function which like aHOC
accepts a component and wrap it to subscribe store’s updates and able to dispatch actions.how it works?
withProvider
component provided by redux we can wrap a component and get the component’s context and children, then any nested components can accessstore
withHooks
andconnect
1
2
3
4
5
6
7
8
9
10
11
12
13
14(mapStateToProps: mapStateToProps, mapDispatchToProps: mapDispatchToProps, mergeProps: mergeProps, options) => ((component) => connectedComponent)
// combine state and component's props and pass to the component, if this argument is passed to the components, then mapStateToProps will be executed as every time the store and ownprops are updated.
type mapStateToProps = (state: object, ownProps?: object) => stateProps
// wrap actions as a part of props pass to the compont
type mapDispatchToProps = (dispatch: Function, props?: object) => dispatchProps
// return an object as a result of mapStateToProps and mapDispatchToProps
type mergeProps = (stateProps, dispatchProps, ownProps) => mapStateToProps & mapDispatchToProps
type stateProps = any
interface dispatchProps {
dispatchPlainObject: () => dispatch(action)
}
middlewares
is used to inject a third-party in the redux proccessing, allow you to do sth (like logging, crash reporting, talking to an asynchronous API, routing, and more) after an action is dispatched and before a reducer update the state.1
(getState: store.getState, action, next: (action) => void) => void
action => middleware => reducer => state
next
is used to passaction
to the next middleware. you can pass the current action to continue the middleware chain or pass another action.middleware chin
: an action can have an array of middleware that is linked bynext
.- tips: if
next
is used in a middleware for passing another action, then that action will be directly to the reducer and will not go through its own middleware chain
- tips: if
- use
dispatch
inside a middleware will stop current middleware chain and start another middleware chin. - it is not different, either use
dispatch
, ornext
, or do nothing to stop middleware chain.
lazy loading
- with
React.lazy
Suspense
import()
, we can lazy loading components and can do something in the fallback which will be triggered if the comonent faild to render - with webpack code spliting, each module loaded by
import()
will be splited in a separate file.
1 | const OtherComponent = React.lazy(() => import('./OtherComponent')); |
concepts
shouldComponentUpdate VS pureComponent
- the former is class componet’s life cycle, by return a boolean in the function to decide whether the dom should update
- the later doesn’t implement
shouldComponentUpdate
, but it has its own way by shallowly compare props and states - PureComponent or manually inplement shouldComponentUpdate are good methods for avoiding needless re-render of children.
virtual DOM
fiber
uncontrolled and controlled component
- when dispose Form elements, like input or select, there are two modes uncontrolled and controlled. this is depending on how deep that you want to control the input.
1 | // uncontrolled, get the value with ref |
automatic batching
batching update
happened when you had multiple state updates, and react will re-render once at the end of a function, not every time thesetState
is called. howerver, this is only occured in a browser event handler. for now in theversion 18
, updates are batched automatically, regardless of what they’re wrapped by.ReactDOM.flushSync()
, this method is used when you don’t want to applyautomatic batching
. updates in this method will be update immediately, and it’s a sync method, since we know that setstate is a async method.1
2
3
4
5
6
7import { flushSync } from 'react-dom'; // Note: react-dom, not react
function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
}
concurrent mode, found in
version 18
- allow us to bounce back and forth between multiple tasks, but doesn’t mean that those tasks are processing at the same time, rather it’s that one task can be paused while other more ugrent task are seen to. once the more urgent one are done, we jump back the less urgent one, bringing with the updated information from the more urgent one.
useTransition
, this hook is used to wraps a less urgent update.
strict modeOffical Doc, this is used only in the DEV mode. when running in this mode:
- activates additional checks and warnings for its descendants
- can be used for any part of your app
- React intentionally double-invokes effects (mount -> unmount -> mount) for newly mounted components in order to flush out unsafe side effects.
coding tips
- refresh page by router according to hash value
1 | this.props.history.replace({ pathname: this.props.location.pathname, search: `id=${id}&api=${window.location.hash.split('&')[1].split('=')[1]}` }) |
- the root element of a component may not need a name
1 | <> |
redux-toolkit
- core api
- createAction,createReducer
- createSlice:including
createAction
andcreateReducer
- PayloadAction:
ts
泛型,用以声明action.payload
createAsyncThunk
accepts a Redux action type string and a callback function that should return a promise. return a standard Redux thunk action creator
web3
window.ethereum (an EIP-1193 compliant provider)
Web3.givenProvider
webpack
module building, browser compatibility, code compressing, code spliting, lazy loading
building proccess
- generate a config from the
webpack.config.js
and the commond line. - use
compiler
module to create acompilation
instance which has access to all modules and their dependencies. execute thecompiler.run()
to start working.compiler
andcompilation
are the heart of webpack, both of them extend fromtapable
. - analysis proccess is started from the
entry
file. useacron parser
to generates AST(Astract Syntax Tree / 抽象语法树) for theentry
file. - traverse through entire AST to create a dependency graph. at this stage, if webpack find any matched
rules
forloader
s, the loaders will convert those codes(e.g. css files) into js, and thenParser
parses them into AST. - this process will be repeatly executed for the each dependency, to recursive traverse.
- bundle all the files.
- in the above proccess
- webpack compiles the different types of file to js file by
loader
sloader
is responsible for file converting. every file type can have more than one loader, those loaders will be invoked with method chaining in order. so the output of a loader will be the arguments of the next loader.
compiler
will throw some hooks when webpack starts/stops, emit assets, watch mode etc. those events can be listend byplugin
and allowsplugin
to intervene the result of output.plugin
can extense features. listen events sended by compiler allows a plugin to effect the result.
- webpack compiles the different types of file to js file by
optimization
tree shaking
compress code
by some plugins, liketerser
,css minimize
code spliting
, useimport()
to split code into multiple chunk andlazy-loading
them.import()
can cooperate withsuspense
feature in react.
tree shaking
after checking
import and exoprt
,tree shaking
will remove the modules which is imported but doesn’t be used. from this point, what method do we use to import file is critical, and we can knowtree shaking
only supportsES module
.to import the specific modules instead of the whole library
1
2
3
4
5
6// Import everything (NOT TREE-SHAKABLE)
import _ from 'lodash';
// CAN BE TREE SHAKEN
import { debounce } from 'lodash';
import debounce from 'lodash/lib/debounce';side effect
refer to a function will effect the variables or scope outside the funcitonhowever, the border between
used
andnot used
is not clean, some modules are started to work when it is imported. sinceobject
is reference type, which means that if a function’s arguments are object, then any changes on we made on it will be easily effect the data outside the function. so there has a propertysideEffects
in thepackage.json
to tellwebpack
whether should betree shaking
.1
2
3
4
5
6
7
8
9
10
11// all the modules have/haven't side effects, and then can't/can be tree shaking
{
"sideEffects": true/false
}
// give webpack an array with side effects
{
"sideEffects": [
"./src/file1.js",
"./src/file2.js"
]
}
module federation
to expose some of our components to the outside, and therefor which can be used in other projects.
this feature is considered as an idea of micro-frontend
HTTP
HTTP Basic
http 请求信息明文传输,
https
- 通过SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密
- 由于HTTPS需要做服务器、客户端双方加密及解密处理,因此会消耗CPU和内存等硬件资源
- 非敏感信息使用 HTTP 通信,在包含个人信息等敏感数据时,才利用 HTTPS 加密通信,且并非对所有内容都进行加密处理,而是仅在那些需要信息隐藏时才会加密,以节约资源。
get && post
- 都包含请求头请求行,post 多了请求 body
- get 多用来查询,请求参数放在 url 中,且有长度限制。post 用来提交,如把账号密码放入 body 中
状态码分类
- 1XX- 信息型,服务器收到请求,需要请求者继续操作。
- 2XX- 成功型,请求成功收到,理解并处理。
- 3XX - 重定向,需要进一步的操作以完成请求。
- 4XX - 客户端错误,请求包含语法错误或无法完成请求。
- 5XX - 服务器错误,服务器在处理请求的过程中发生了错误。
三次握手 make suring that both the service and client have ability to send and receive data
- 1:客户端发送网络包,服务端收。服务端得出结论:客户端的发送能力、服务端的接收能力正常的。
- 2:服务端发包,客户端收。客户端得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
- 3:客户端发包,服务端收。服务端得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
post 请求序列化:use formdata object、querystring 库
content-type:
- application/json:json数据格式
- application/x-www-form-urlencoded:数据被编码为名称/值对,fromdata格式。
- multipart/form-data: 在表单中上传文件时,数据被编码为一条消息,http协议会对参数进行分割
- text/plain: 数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符。postman软件里标的是RAW。
传 参
- 保留字符 :
: / ; ? #
- encodeURI 和 decodeURI 函数操作的是完整的 URI,不会编码保留字符。
- encodeURIComponent 和 decodeURIComponent 函数操作的是组成 URI 的个别组件,会编码任何保留字符
- 保留字符 :
Restful api(Representation state transfer)
- only noun no verb in the url
- what is this request for from the url
- what is this request wanna do from the http method
- what is the result from the http status code
Vscode
vscode setting
1 | { |
short key | function |
---|---|
Ctrl+Shift+[ | 折叠 |
Ctrl+Shift+] | 展开 |
ctrl+d | 选中单词 |
alt+shift+鼠标点选 | 多个位置 |
alt +鼠标点选 | 选中 |
alt + z | word break |
ctrl + shift + L | pitch on the same words simultaneously |
ctrl + shift + p | show command menu |
Setting json | C:\Users\tong\AppData\Roaming\Code\User |
Line break | “files.eol”: “\n” |
ctrl + g | go to a specif line |
terms
en | ch |
---|---|
closed testing | 精密测试 |