After a recent cursory reading of JavaScript you Don’t Know, here are a few things I think I might forget and need to remember

To get up

3. Function scope and block scope

Disadvantages of anonymous functions

1. No meaningful function names are displayed in the stack trace. Makes debugging difficult

2, no function name, difficult to reference

3. Poor readability and understandability

4,

4.3 Function preference

foo()					// 1 function foo promotes var foo first and repeated declarations are ignored
var foo
function foo(){
    console.log(1)}var foo = function(){
    console.log(2)}Copy the code

5. Scope closure (for loop preserves I after each iteration)

5.2

Closures occur when a function can remember and access its lexical scope

5.3

Whenever you use a callback function, you’re actually using a closure

The second part

2.2.2.1

The default binding cannot be used in strict mode

function foo(){
    "use strict"
    console.log(this.a)
}
var a = 2
foo() // TypeError: this is undefined
Copy the code

Although the binding rules for this depend entirely on the call location, the global object is only called by default when not in strict mode,

In strict mode it is independent of where foo is called

function foo(){
    console.log(this.a)
}
var a = 2
(function(){
    "use strict";
	foo() / / 2}) ()Copy the code

2.2.2 Implicit Loss

The following

function foo(){
    console.log(this.a)
}
var obj = {
    a:2.foo:foo
}
var bar = obj.foo
var a = 'global_a'
bar() // global_a
Copy the code

Hard binding such as bind call can solve this problem

var bar = obj.foo.bind(obj)
var bar = () = >{obj.foo.call(obj)}
Copy the code

Small point: The second argument to forEach is referred to as this

2.2.4 new binding

When new is called, do the following

  • Create a brand new object
  • This new object will be connected by the implementation prototype
  • Modify this to point to
  • Return this object

2.4.3 soft binding


function foo(){
  console.log(this.name);
}
var obj1 = {name:'obj1'},obj2 = {name:'obj2'};
let fooObj = foo.bind(obj1);
fooObj();			// obj1
fooObj.call(obj2);	// obj1
Copy the code

You can’t change this after hard binding. FooObj is equivalent to (easy, saves some steps)

fooObj = () = >{
    let arg = [].prototype.slice(arguments.1)
    return foo.apply(obj1,arg)
}
Copy the code

So no more external calls

The principle of

If this is global or undefined, the object is specified by default. Otherwise, this is not modified

The third part

3.3.5 Attribute Descriptors

Object.getOwnPropertyDescriptor(myObject,'a')
Copy the code

3.3.6 invariance

methods code explain
Prohibit extensions Object.preventExtensions(myobject) Unable to extend new properties
seal Object.seal() You cannot add new properties or reconfigure or delete any existing properties

The existing object preventExtensions is called and marks all properties as 64x :false
freeze Object.freeze() This is equivalent to calling seal on existing objects and marking writable:false

3.3.10 existence

let myObj = {a:2}
(a in myObj)					// Is there any object and prototype on the chain
myObj.hasOwnProperty('a')		// Whether the object myObj exists
myObj.propertyIsEnumberable('a')	// Whether enumerable

Copy the code

X Manually view iterator

var myArray = [1.2.3];
var it = myArray[Symbol.iterator]()
it.next();
it.next();
it.next();
it.next();
Copy the code

Es implementation P123

Object.defineProperty(myObject,Symbol.iterator,{
    writable:false.enumberable:false.configurable:true.
    value(){
    	const o = this;
    	let idx = 0;
    	let ks = Object.keys(o);
		return {
            next(){
                return {
                    value:o[ks[idx++]],
                	done:(idx>ks.length)
                }
            }
        }
	}
})
Copy the code

class

inheritance

Chapter 5 Prototype

5.1.2 Setting and Masking properties

Set myObject.foo = ‘bar’ in three cases

  • If foo is on the prototype chain and is not marked as read-only, a foo attribute is added directly to myObject
  • If foo exists on the stereotype chain but is marked as read-only, existing properties cannot be modified or created, and strict mode throws an error
  • If foo exists at the top of the prototype chain and is a setter, it will be called, neither changing what already exists nor creating something new

5.3 Prototype Association

There will be flaws in the way

Bar.prototype = Foo.prototype // Direct references will result in simultaneous modifications
Bar.prototype = new Foo()	// If Foo has side effects, they will affect bar descendants, such as writing logs to modify stateCorrect method bar.prototype =Object.create(Foo.prototype)
Copy the code

Object. The create polyfill

if(!Object.create){
    Object.create=function(o){
        function F()
        F.prototype = o
        return new F()}}Copy the code

Medium Volume (Part I)

The second chapter

2.3.1 Syntax of Numbers (toFixed)

let a = 42.59
a.toFixed(1) // 42.6 is rounded
42.toFixed(3)	//SyntaxError

(42).toFixed(3)
0.42. toFixed(3)
42..toFixed(3)
Copy the code

2.3.2 Compare the size of the values

0.41 + 0.2 = = = 0.3; //false Binary floating-point numbers are not very precise

Setting a range of errors is often called machine accuracy

if(!Number.EPSILON){
    Number.EPSILON = Math.pow(2, -52)}// Check whether two numbers are equal
function numberIsEqual(){
    return Math.abs(n1-n2)<Number.EPSILON;
}
Copy the code

2.3.4 Integer Detection

Number.isInteger(42)		// true
Number.isInteger(42.000)	// true

//	polyfill
if(!Number.isInteger){
    Number.isInteger = function(num){
        return typeof num == 'number' && num%1= =0}}Copy the code

2.4.3 isNaN has a strict defect

var a = 2/'foo'
var b = 'foo'
window.isNaN(a)	//true
window.isNam(b)	//true

NumberThe isNaN polyfillif(!Number.isNaN){
    Number.isNaN = function(n){
        returnn! =n } }Copy the code

2.4.. 4 Special Equations ()

Object.is()
if(!Object.is){
    Object.is = function(v1,v2){
        if(v1===0&&v2===0) {return 1 / v1 === 1/v2 / / + 0 judgment
        }
        if(v1 ! == v1){returnv2 ! == v2/ / NaN's judgment
        }
        return v1 === v2
    }
}
Copy the code

The fourth chapter

2 the toString

var a = 1.07*Math.pow(10.21)
a.toString()	/ / 1.07 e21
Copy the code

stringify

1. If an object has a toJSON method, that method is used and its return value is serialized

let obj = {
  name:'test'.age:'18'.toJSON(){
    return {result:'this is result'}}}console.log(JSON.stringify(obj))
Copy the code

2. The method takes a second argument

- Array: represents the properties to be serialized. - Function: calls the object itself once, then each property in the object once, passing two arguments and values at a time, and returning undefined if a key is to be ignoredCopy the code
let a = {a:'valuea'.c:'valuec'.d:'valued'}
JSON.stringify(a,['b'.'c']);
JSON.stringify(a,function(k,v){
    if(k! = ='c') return v
})
Copy the code

3. The third parameter indicates the indentation.

- Number indicates the number of characters to indent at each level - the first character of the string is used for each level of indentationCopy the code
let a = {a:'valuea'.c:'valuec'.d:'valued'};
JSON.stringify(a,null.3);
JSON.stringify(a,null."-- -- -- -- -- -")
Copy the code

4.2.2 toNumber

undefined -> NaN

null -> 0

ToNumber principle (toPrimitive (y))

  • Determines if a valueOf() method exists, and if it does, returns a primitive type value and uses that value for the cast
  • If not, the return value of toString() is used for the cast
  • TypeError is generated if neither valueOf() nor toString() returns a primitive type value

4.3.1

The date display is converted to numbers

Use + to force a Date object to a number to return a timestamp

let d = new Date('Tue Jul 13 2021 22:42:03 GMT+0800 ')
console.log(+d)
Copy the code

The above usage is generally not recommended

You can use data.now to get the current time, and new date.getTime () to get the timestamp for the specified time

4.3.2 Displaying parsed Numeric Strings

ParseInt parsing allows non-numeric occurrences

Number conversions do not allow non-numbers

var a = '42px'
Number(a) // NaN
parseInt(a) / / 42
Copy the code

ParseInt is converted to a string and parsed

var a = {
    num:21.toString(){
        return String(this.num*2)}}parseInt(a)	/ / 42
Copy the code

ParseInt The second argument

4.4.2 Implicit Casting

A + ‘ ‘

var a = {
    valueOf(){
        return 42;
    },
    toString(){
        return 4
    }
}
a + ' ';	/ / '42'
String(a);	/ / '4'
Copy the code

[3] – [2]

var a = [3];
var b = [1];
a - b; / / 2ToString () is called first and then converted to a numberCopy the code

= =

42= =The '42' // The string is converted to a number true42'= =true	// Also convert to the number false
null= =undefined // true
[1.2.3] = ='1, 2, 3' / / true [1, 2, 3] - > '1, 2, 3'
Copy the code

Conversion between objects and non-objects

The object is converted to a string or number by the toPrimitive abovevar  a = 'abc'
var b = Object(a)
a == b	//true

var a = null
var b = Object(a)	// Same as Object()
a == b				//false

var a = undefined
var b = Object(a)	// Same as object()
a == b				//false

var a = NaN / / same as above
Copy the code

== and === Application scenarios

If the values in both sides aretrueorfalseDo not use == have [],"".0Do not use ==Copy the code

The fifth chapter

try catch(P118)

The function terminates here if an exception is thrown in finally, and the value is invalidated if it has been returned before

The reeturn in finally overrides the return in the try and catch

function foo(){
    try{
        return 42
    }
    finally{
        throw 'Oops! '
    }
    console.log('nerver runs')}console.log(foo()) //error Uncaught Oops! (line 11)
Copy the code

Middle Volume (Part II)

The first chapter

1.4.3 collaboration

After the Ajax request comes back, n pieces of data are requested in batches

let res = []
function response(data){
    var chunk = data.splice(0.1000);
    res = res.concat(chunk.map(value= >value*2))
    if(data.length>0) {setTimeout(() = >{
           response(data) 
        },0)}}Copy the code

Chapter 2: Save some callbacks

2.4 Handling Timeout

Some processing of the request timeout

function timeoutify(fn,delay){
    let timmer = setTimeout(() = >{
        timmer = null
        fn(new Error('timeOut'))
    },dealy)
    return function(){
        if(timmer){
            clearTimeout(timmer)
            fn.call(this.arguments)}}}foo(err,data){
    if(err){
        console.error(err)
    }else{
        console.log(data)
    }
}
ajax('http://..... ',timeoutify(foo,500))
Copy the code

The third chapter Promise

3.3.2 Calling too late (note the Promise expansion)

Resolve expands a Promise asynchronously (simply by replacing the Promise with the outer Promise), while Reject returns the value

var p3 = new Promise((resolve,reject) = >{
    resolve('B')})var p1 = new Promise((resolve,reject) = >{
    resolve(p3)
})
var p2 = new Promise((resolve,reject) = >{
    resolve('A')
})
p1.then(value= >{
    console.log(value)
})
p2.then(value= >{
    console.log(value)
})

// B A
Copy the code

Promise.race can be used for timeout operations

Chapter 4 Generators

4.1.1

In general, one more next is required than yield.

function *fn(){
    let a = 1;
    yield 10;
    a += (yield)
    console.log(a)
}
let test = fn()
test.next()
test.next()
test.next(10)
Copy the code

The above code is a little simpler

  • The first time next runs to the first yield, the yield value is returned (done:false,value:10).
  • Second run next to the second yield, yield no value, namely returns undefined (done: false, value: undefined)
  • After third next run the whole project, yield no value Returns undefined (done: true, value: undefined)

4.2.1 Implement iterator interface for generators

for.. Principle of execution of
let something = (function(){
  var nextVal=108;
  return {
      // for.. Properties required for the of loop
    [Symbol.iterator]:function(){return this},
    next(){
       if(nextVal === undefined){
         nextVal = 1
       }else{
         nextVal = (3 * nextVal) + 6
	   }
      return {done:false.value:nextVal}
    }
  }
})()
for(let item of something){
  if(item < 100) {console.log(item)
  }
}
// In an array
let arr = [1.2.3.4.5]
let it = arr[Symbol.iterator]();
console.log(it.next())
Copy the code
Executing a generator also results in an iterator

function *scq(){
  let nextVal
  while(true) {if(nextVal === undefined){
      nextVal = 10
    }else{
      nextVal += 10
    }
    yield nextVal
  }
}
for(let item of scq()){
  if(item < 100) {console.log(item)
  }
}
Copy the code

You can terminate manually using an external return


function *scq(){
  try{
      let nextVal
      while(true) {if(nextVal === undefined){
          nextVal = 10
        }else{
          nextVal += 10
        }
        yield nextVal
      }
  }
  finally{
      console.log('cleaning up! ')}}let it = scq()
for(let item of it){
  if(item < 100) {console.log(item)
  }else{
      console.log(it.return('all over'))}}// Output the result
//... A string of Numbers


//"cleaning up!"
//[object Object] {
// done: true,
// value: "all over"
/ /}
Copy the code

Ed.

2.4.1 Object Attribute Assignment mode

let a = {x:12.y:14}
let {x,y} = a {x:x,y:y} = a
Copy the code

The x of x omitted above:

That is to say, {x:x in the first part of x: fixed writing, the back can be flexible

The following

let a = {x:12.y:14};
let {x:abc,y:def} = a
console.log(abc);	/ / 12
console.log(def);	/ / 14
Copy the code

2.5.1 Setting Default Values

let arr = [1.2.3]
let [arra=11,arrb=12,arrc=13,arrd=14] =arr
console.log(arra,arrb,arrc,arrd)
 
let obj={a:21.b:22}
let {a:obja=31.b:objb=32.c:objc=33} = obj
console.log(obja,objb,objc)
Copy the code

2.5.3 Structural Parameters

DefaultConfig is the default setting and is an example of BTN setting

What you want to do now is to pass the Settings from defaultConfig to BTN without changing BTN’s existing Settings

Plan a
let defaultConfig = {
  options: {click:true.input:true,},css: {color:'white'.background:'blue'}}let btn = {
  options: {click:true.input:false
  }
}
btn = Object.assign({},defaultConfig,btn)
console.log(btn)
Copy the code

However, this mode is a shallow copy. Changing attributes in the BTN will change the attributes in the default configuration

Scheme 2
let defaultConfig = {
  options: {click:true.input:true,},css: {color:'white'.background:'blue'}}let btn = {
  options: {click:true.input:false}}// btn = Object.assign({},defaultConfig,btn)
// console.log(btn)
{
    let {
      // options The default value is null. If BTN has this value, the value in BTN will be used
      options: {// Default set click to the value in defautlConfig,btn.config to use the corresponding value if there is a corresponding value
        click=defaultConfig.options.click,
        input=defaultConfig.options.input,
      }={},
      css:{
        color=defaultConfig.css.color,
        background=defaultConfig.css.background
      }={}
    } = btn
    // when the top is exposed {click... ,input.. }, refer to the following expression
    // let {a:x} = {a:18} console.log(x)
    btn = {
      options:{click,input},
      css:{color,background}
    }
}
console.log(btn)
Copy the code

2.10.3 Regular Expression Flags

View the content and identifier of the regular expression

  • Es6 specifies that the expressions output gimuy in this order
let re = /foo/ig
re.flags;	//gi
re.source	//foo
Copy the code

3.4.2 extends and super

P173 extends native classes

class MyCollArray extends  Array{
  firstItem(){
    return this[0]}lastItem(){
    return this[this.length-1]}}let arr = new MyCollArray('a'.'b'.'c')
console.log(arr.firstItem());	//a
console.log(arr.lastItem());	//c
Copy the code
'foo'.repeat(3)	//'foofoofoo'
Copy the code