Some forgotten things (2)

The reason/function of Symbol

① To avoid attribute conflict and duplication as an attribute, it is to use it to represent a unique value;
the question is under what circumstances should we ensure that attributes will not conflict and be overridden repeatedly?
There are this.$ parent, this.$ options, this.$ set in vue. Using $ to start the name is to reduce repeated coverage through the naming convention. However, the naming convention is not enforced, and it may still be overwritten by new low-level programmers
. It is possible
to freeze an object by using Object.freeze before there is no Symbol. It will definitely not overwrite or modify the properties. However, the problem it brings is that it loses flexibility. If you only want one property to not be overwritten and repeated, the entire Objects are frozen, which is not worth the gain.

Object.defineProperty(obj,'a',{ writable:false }) is also required to achieve the purpose of not being able to overwrite a property by shielding the writability of a property. The disadvantage is trouble. It is easiest to use symbols.
** Function 1: Prevent variable name conflicts, global method attribute objects hanging under the window, etc., as well as global status, etc. There are many places where uniqueness needs to be ensured. **

//订单已付款 
if(orderStatus==='payed'){
    
    
//就干点啥
}
//订单已经取消 就干点啥
if(orderStatus==='cancel'){
    
    
//就干点啥
}

What are the problems with this writing method?
1. The paid cancel string may be written incorrectly when used in multiple places;
2. The string may need to be modified because it is considered to have inaccurate meaning
3. It is difficult for others to know the orderStatus at a glance What statuses are
changed to the following:

const OrderStatus={
    
    
payed:Symbol('payed'),
cancel:Symbol('cancel')
}
//订单已付款 
if(orderStatus===OrderStatus.payed){
    
    
//就干点啥
}
//订单已经取消 就干点啥
if(orderStatus===OrderStatus.cancel){
    
    
//就干点啥
}

** Function 2: Replace strings, standardize code, and reduce errors. **

The role and use of BigInt

Function:
BigInt is a numeric type of data that can represent integers in any precision format. BigInt can be used to safely store and operate large integers, even if the number exceeds the safe integer range that Number can represent.
use:

  let max = Number.MAX_SAFE_INTEGER;//Number的最大安全整数
  console.log(max);
  console.log(max + 1);
  //超过number的最大数值范围,运算就会出错
  console.log(max + 2);
  
  console.log(BigInt(max));
  //BigInt数据类型不能直接和普通数据类型进行运算
  console.log(BigInt(max) + BigInt(1));
 console.log((BigInt(max) + BigInt(2)));
 console.log((BigInt(max) + BigInt(2)).toString());

There is an n after bigint to distinguish the Number type. You can call the tostring method on bigint to convert it to a string.
Insert image description here

typeof symbol and typeof bigint now return symbol and bigint

Understanding of heap and stack

1. The stack is automatically allocated memory space, which is automatically released by the system; while the heap is dynamically allocated memory, and the size may not be automatically released. 2.
Reference type data stored in the stack memory is actually the object stored in the heap memory. The reference address in . Through this reference address, you can quickly find the object saved in the heap memory.
3. Basic data types are stored on the stack, and reference data types are stored on the heap.
Insert image description here

instanceof

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){
    
    } instanceof Function);       // true
console.log({
    
    } instanceof Object);                   // true

It can be seen that instanceof can only correctly determine the reference data type, but not the basic data type . The instanceof operator can be used to test whether an object has a constructor's prototype attribute in its prototype chain.

constructor determines type

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {
    
    }).constructor === Function); // true
console.log(({
    
    }).constructor === Object); // true

The constructor has two functions, one is to determine the type of data, and the other is that the object instance accesses its constructor through the constrcutor object. It should be noted that if you create an object to change its prototype, the constructor cannot be used to determine the data type: Let’s
analyze here (2).constructor === Number) or

var str1 = "oujm";
var str2 = str1.substring(2);

A basic type should not have properties and methods such as constructor and substring, so why can we call these?
We have overlooked that in the JS world there is an object type called a wrapper object .
In fact, whenever a basic type is read, an object of the corresponding basic wrapper type is created in the background.
Looking at the one above again, str1 is obviously a basic type instance. The problem lies in str1.substring(2). How can strings have methods? In fact, in order to allow us to better operate instance objects of basic types, a series of operations are performed in the background:

Create an instance of String,
call the specified method on the instance,
and destroy the instance.

It can be seen from here that the only difference between general reference types and package types is the life cycle of the object. The life cycle of wrapped type objects is very short, only for a moment when the code is executed, and then it is destroyed, so this is why we cannot add properties and methods to basic type values ​​at runtime.
This also answered a question I had

var str1 = "oujm";
var str2 = new String("ethan");

console.log(str1.__proto__ === str2.__proto__); // true
console.log(str1 instanceof String); // false 
console.log(str2 instanceof String); // true 

In the same way, when calling the __proto__ attribute, new String() is used to instantiate an object first, so at that moment their constructors and prototype objects are the same, but only for that moment.

The difference between Object.prototype.toString.call() and calling toString directly

This is because toString is the prototype method of Object, and types such as Array and function, as instances of Object, all override the toString method . When different object types call the toString method, based on the knowledge of the prototype chain, the corresponding rewritten toString method is called (the function type returns a string with the content of the function body, the Array type returns a string composed of elements...), and The prototype toString method on Object will not be called (returning the specific type of the object) , so using obj.toString() cannot get its object type, and can only convert obj to a string type; therefore, when you want to get the specific type of the object , the toString method on the Object prototype should be called.

How to judge an array

Object.prototype.toString.call()
obj. proto === Array.prototype; Same as instanceof,
use ES6’s Array.isArray() to judge
a.constructor===Array

Why is the result of typeof null Object?

In the first version of JavaScript, all values ​​were stored in 32-bit units, each unit containing a small type tag (1-3 bits) and the actual data of the current value to be stored. Type labels are stored in the low bits of each cell, and there are five data types:

000: object   - 当前存储的数据指向一个对象。
  1: int      - 当前存储的数据是一个 31 位的有符号整数。
010: double   - 当前存储的数据指向一个双精度的浮点数。
100: string   - 当前存储的数据指向一个字符串。
110: boolean  - 当前存储的数据是布尔值。

If the lowest bit is 1, the length of the type label flag is only one bit; if the lowest bit is 0, the length of the type label flag is three bits, providing an additional two bits for storing the other four data types.
There are two special data types:

The value of undefined is (-2)30 (a number beyond the range of integers);
the value of null is the machine code NULL pointer (the value of the null pointer is all 0)

That means that the type label of null is also 000, which is the same as the type label of Object, so it will be judged as Object.

valueOf function

Returns the original value of the given object.
Insert image description here
Insert image description here
You can also use the valueOf method to invert the wrapped type to the basic type:

var a = 'abc'
var b = Object(a)
var c = b.valueOf() // 'abc'

The this point inherited by the arrow function will never change. Call(), apply(), bind() and other methods cannot change the point of this in the arrow function. The arrow function has no prototype.

var id = 'GLOBAL';
Object.prototype.id='111'
var obj = {
    
    
  id: 'OBJ',
  a: function(){
    
    
    console.log(this.id);
  },
  b: () => {
    
    
    console.log(this.id);
  }
};
new obj.a()  // 111
new obj.b()  // Uncaught TypeError: obj.b is not a constructor

Pay attention to the last step of new operation

(1) First create a new empty object
(2) Set the prototype and set the prototype of the object to the prototype object of the function.
(3) Let the this of the function point to this object and execute the code of the constructor (add attributes to this new object)
(4) Determine the return value type of the function. If it is a value type, return the created object. If it is a reference type, an object of this reference type is returned.
Determine the result logic of return

result && (typeof result === "object" || typeof result === "function");

What is a tail call? what are the benefits

A tail call refers to the last step of a function calling another function. Code execution is based on the execution stack, so when another function is called within a function, the current execution context will be retained, and then another execution context will be created and added to the stack. If you use tail call, because it is the last step of the function, you no longer need to retain the current execution context, thus saving memory. This is tail call optimization. However, ES6's tail call optimization is only enabled in strict mode, and is invalid in normal mode.

function f(x){
    
    
  return g(x);
}

The difference between Es6 and commonJs

Documentation link

for... in will traverse the entire prototype chain of the object, and the performance is very poor

Advantages and disadvantages of fetch requests

Fetch
fetch is known as a replacement for AJAX. It appeared in ES6 and uses the promise object in ES6. Fetch is designed based on promises. The code structure of Fetch is much simpler than ajax. Fetch is not a further encapsulation of ajax, but native js, which does not use the XMLHttpRequest object.
Advantages of fetch:

The syntax is concise and more semantic.
It is implemented based on standard Promise, supports async/await
at a lower level, and provides rich APIs (request, response)
without XHR, which is a new implementation method in the ES specification.

Disadvantages of fetch:

fetch only reports errors for network requests, and treats 400 and 500 as successful requests. When the server returns 400 and 500 error codes, it will not be rejected . Only when network errors cause the request to fail to be completed, fetch will be rejected.
Fetch does not carry cookies by default. You need to add configuration items: fetch(url, {credentials: 'include'})
fetch does not support abort and does not support timeout control . Timeout control implemented using setTimeout and Promise.reject cannot prevent the request process. Continuing to run in the background results in a waste of traffic.
Fetch has no way to natively monitor the progress of the request, but XHR can

Can forEach change the original array?

Documentation link

The difference between every and some

Documentation link

Usage scenarios of Promise's Race

Insert image description here

How to avoid backflow?

1. Use absolute or fixed elements to separate the elements from the document flow, so that their changes will not affect other elements. 2.
Put multiple read operations (or write operations) of the DOM together instead of reading and writing operations interspersed with writing. . This is due to the browser's rendering queue mechanism.
The browser has optimized itself for reflow and redraw of the page - the rendering queue
browser will put all reflow and redraw operations in a queue. When the operations in the queue reach a certain number or reach a certain time interval, the browser will batch the queue. This will turn multiple reflows and redraws into one reflow and redraw.
Above, when multiple read operations (or write operations) are put together, they will be executed after all read operations enter the queue. In this way, instead of triggering multiple reflows, only one reflow is triggered.

Throttling scene: animation scene: avoid performance problems caused by triggering animation multiple times in a short period of time

code output

const promise = new Promise((resolve, reject) => {
    
    
  console.log(1);
  console.log(2);
});
promise.then(() => {
    
    
  console.log(3);
});
console.log(4);

code

Promise.resolve(1)
  .then(res => {
    
    
    console.log(res);
    return 2;
  })
  .catch(err => {
    
    
    return 3;
  })
  .then(res => {
    
    
    console.log(res);
  });

The reason why the above output results print out 1 and 2 in sequence is because the first then method is used after resolve(1) and does not enter the catch, so the res in the second then actually gets the first The return value of then. And return 2 will be packaged into resolve(2), and 2 will be printed out by the final then.

Code question:

Promise.reject('err!!!')
  .then((res) => {
    
    
    console.log('success', res)
  }, (err) => {
    
    
    console.log('error', err)
  }).catch(err => {
    
    
    console.log('catch', err)
  })

The output is as follows:
error err!!!

We know that the two parameters in the .then function are:

The first parameter is the function used to handle Promise success.
The second parameter is the function used to handle failure.

In other words, the value of Promise.resolve('1') will enter the successful function, and the value of Promise.reject('2') will enter the failed function.
In this question, the error is directly captured by the second parameter of then, so it will not be captured by catch. The output result is: error err!!!'
However, if it is like the following:

Promise.resolve()
  .then(function success (res) {
    
    
    throw new Error('error!!!')
  }, function fail1 (err) {
    
    
    console.log('fail1', err)
  }).catch(function fail2 (err) {
    
    
    console.log('fail2', err)
  })

If an error is thrown in the first parameter of then, it will not be caught by the second parameter, but will be caught by the subsequent catch.
Code question:
finally is essentially a special case of the then method

Promise.resolve('1')
  .finally(() => {
    
    
    console.log('finally1')
    throw new Error('我是finally中抛出的异常')
  })
  .then(res => {
    
    
    console.log('finally后面的then函数', res)
  })
  .catch(err => {
    
    
    console.log('捕获错误', err)
  })

'finally1'
'Catch error' Error: I am an exception thrown in finally

Code question

var length = 10;
function fn() {
    
    
    console.log(this.length);
}
 
var obj = {
    
    
  length: 5,
  method: function(fn) {
    
    
    fn();
    arguments[0]();
  }
};
 
obj.method(fn, 1);

Output: 10 2

Analysis:

When fn() is executed for the first time, this points to the window object and 10 is output.
The second execution of arguments0 is equivalent to arguments calling the method. this points to arguments, and two parameters are passed here, so the length of the output arguments is 2.

code

function foo(something){
    
    
    this.a = something
}

var obj1 = {
    
    }

var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a); // 2

var baz = new bar(3);
console.log(obj1.a); // 2
console.log(baz.a); // 3

Code:

(function(){
    
    
   var x = y = 1;
})();
var z;

console.log(y); // 1
console.log(z); // undefined
console.log(x); // Uncaught ReferenceError: x is not defined

The key to this code is: var x = y = 1; In fact, it is executed from right to left. First, y = 1 is executed. Because y is not declared with var, it is a global variable, and then the second step is Assigning y to x means assigning a global variable to a local variable. Ultimately, x is a local variable and y is a global variable, so printing x is an error.

classic

function a() {
    
    
    var temp = 10;
    function b() {
    
    
        console.log(temp); // 10
    }
    b();
}
a();

function a() {
    
    
    var temp = 10;
    b();
}
function b() {
    
    
    console.log(temp); // 报错 Uncaught ReferenceError: temp is not defined
}
a();

The scope chain of variables in js is related to the environment when it is defined, not when it is executed. The execution environment will only change this, passed parameters, global variables, etc.

Prototype:
console.log(Object.proto ) //Function.prototype

Code:

// a
function Foo () {
    
    
 getName = function () {
    
    
   console.log(1);
 }
 return this;
}
// b
Foo.getName = function () {
    
    
 console.log(2);
}
// c
Foo.prototype.getName = function () {
    
    
 console.log(3);
}
new Foo().getName();     // 3
new new Foo().getName(); // 3

new Foo().getName(), which is equivalent to (new Foo()).getName(), first new an instance of Foo, and then execute the getName method of this instance, but this instance itself does not have this method, so go to the prototype Look up the chain __protot__, instance.protot === Foo.prototype, so the output is 3;
new new Foo().getName(), which is equivalent to new (new Foo().getName()), as above 6 , first output 3, and then new an instance of new Foo().getName().

code

function A(){
    
    
}
function B(a){
    
    
  this.a = a;
}
function C(a){
    
    
  if(a){
    
    
this.a = a;
  }
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
 
console.log(new A().a);
console.log(new B().a);
console.log(new C(2).a);

Implement a simple useState

let memoizedState = []; // 存放hooks
let cursor = 0; // 当前 memoizedState 下标
function reRender() {
    
    
  cursor = 0;
  ReactDOM.render(<App />, rootElement);
}
// 如果是初次执行useState,使用传入的初始值。 更新环节使用缓存的值
function useState(initialValue) {
    
    
  memoizedState[cursor] = memoizedState[cursor] || initialValue;
  const currentCursor = cursor;

  const setState = newState => {
    
    
    memoizedState[currentCursor] = newState;
    reRender();
  };

  return [memoizedState[cursor++], setState]; // 返回当前 state,并把 cursor 加 1
}

How are useEffect's dependency arrays compared?

useEffect performs a shallow comparison on dependencies, that is, Object.is (arg1, arg2), which may be due to performance considerations. For primitive types this is no problem, but for reference types (arrays, objects, functions, etc.) it means that even if the value inside remains the same, the reference itself changes, causing useEffect to perform side effects.

Too many 304 status codes may cause the following problems:

Website snapshots stopped;
inclusion decreased;
weight decreased.

OPTIONS request method and usage scenarios

OPTIONS is one of the HTTP request methods besides GET and POST.
The OPTIONS request method has two main uses:

Get all HTTP request methods supported by the server;
used to check access permissions. For example: when performing CORS cross-domain resource sharing, for complex requests, the OPTIONS method is used to send sniffing requests to determine whether there is access permission to the specified resource.

What is a digital certificate?

The current method is not necessarily safe, because there is no way to determine that the public key obtained is a safe public key. There may be an intermediary who intercepts the public key sent to us by the other party, and then sends his own public key to us. When we use his public key to encrypt the information sent, he can decrypt it with his own private key. Then he pretended to be us and sent information to each other in the same way, so that our information was stolen, but he didn't know it yet. To solve such problems, digital certificates can be used.
First, a Hash algorithm is used to encrypt the public key and other information to generate a message digest, and then a credible certification center (CA for short) uses its private key to encrypt the message digest to form a signature. Finally, the original information and signature are combined, called a digital certificate. When the recipient receives the digital certificate, it first uses the same Hash algorithm to generate a digest based on the original information, then uses the public key of the notary office to decrypt the digest in the digital certificate, and finally compares the decrypted digest with the generated digest. By comparison, you can find out whether the obtained information has been changed.
The most important thing about this method is the reliability of the certification center. Generally, browsers will have certificates from some top-level certification centers built into them, which means we automatically trust them. Only in this way can data security be ensured.

Does DNS use tcp or udp?

DNS occupies port 53 and uses both TCP and UDP protocols.
(1) Use TCP protocol during zone transfer
(2) Use UDP protocol during domain name resolution
this topic

var length = 10;

function fn() {
    
    

 return this.length

}

var obj = {
    
    

 length: 5,

 test1: function() {
    
    
let f=function(){
    
    
    return this
}
//this是运行时确定的,指向要看调用方式,比如a的this是test1中的this,他是通过obj.的形式调用的,所以this为obj
//b是直接执行的,没有隐式绑定和显式绑定,所以this为window,c也是直接执行的,this为window
const a=this.length
const b=f();
const c=fn()
return [a,b,c]
 }

};
console.log(obj.test1())

a question

var func1 = x => x;
var func2 = x => {
    
    x}; 
var func3 = x => ({
    
    x});
console.log(func1(1));
console.log(func2(1));
console.log(func3(1));

Commonly used meta tags

What is the meta tag? The
meta tag is defined by the name and content attributes. It is used to describe the attributes of the web page document, such as the author of the web page, web page description, keywords, etc.
1. charset, used to describe the encoding type of the HTML document
2. viewport, adaptation On the mobile terminal, you can control the size and proportion of the viewport:
Insert image description here
the code
scope is static and is determined when it is declared; this is dynamic and is determined at runtime.

const list = [1, 2, 3];
const square = (num) => {
    
    
    return new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            resolve(num * num);
        }, 1000);
    });
}

function test() {
    
    
    list.forEach(async (x) => {
    
    
        const res = await square(x);
        console.log(res);
    });
}
test()
//相当于下面
new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            resolve()
}, 1000)
    }).then(res=>{
    
    
        console.log(1)
    })
    new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            resolve()
}, 1000)
    }).then(res=>{
    
    
        console.log(4)
    })
    new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
            resolve()
}, 1000)
    }).then(res=>{
    
    
        console.log(9)
    })

this topic

 inner = 'window';

var obj1 = (function() {
    
    
    var inner = '1-1';
    return {
    
    
        inner: '1-2',
        say: function() {
    
    
            console.log(inner);
            console.log(this.inner);
        }
    }
})();

var obj2 = (function() {
    
    
    var inner = '2-1';
    return {
    
    
        inner: '2-2',
        say: function() {
    
    
            console.log(inner);
            console.log(this.inner);
        }
    }
})();


obj1.say();
obj1.say = obj2.say;
obj1.say();

For a div, set the width of its parent div to 100px, and then set its padding-top to 20%.

How high is the current div? What if the parent element is positioned absolutely?
The height of the existing div is equal to its own height + the width of the parent block * 20%. If the parent element positioning is absolute, the result remains unchanged;

When margin/padding takes a value in the form of a percentage, whether it is left/right or top/bottom, the width of the parent element is used as a reference!
If the padding and margin of the child element are judged based on the height of the parent element, it will fall into an infinite loop.

What is the difference between for in and for of?

for in applied to an array
Using for-in will traverse all enumerable properties of the array, including the prototype. The prototype method method and name attribute will be traversed. It is usually necessary to cooperate with the hasOwnProperty() method to determine whether a certain attribute is an instance attribute of the object to remove the prototype object from the loop.

Array.prototype.sayHello = function(){
    
    
    console.log('hello');
}
 
Array.prototype.str = 'world'
var myArray = [1,2,10,30,34]
myArray.name = '数组'
for (const key in myArray) {
    
    
    console.log(key);
}
//迭代的是属性key,不是值。
//结果 0 1 2 3 4 name sayHello str

Therefore, for in is suitable for traversing the key-value pairs in the object, and for of is suitable for traversing the array.

Why useRef?

Saving the reference of the DOM element
In the function component, we cannot directly use this to obtain the reference of the DOM element like in the class component. UseRef can be used to save references to DOM elements so that we can obtain or modify their attributes.

Saving component state
In functional components, all variables are redeclared and initialized every time the component is re-rendered. In order to retain some data between multiple renders, we can use useRef to save this data and they will remain unchanged throughout the lifetime of the component.

Avoid re-rendering performance issues
In some cases, we need to save some data, but this data does not need to trigger re-rendering. If useState is used, each update of these data will trigger the re-rendering of the component, thus wasting performance. Using useRef can avoid this problem.

code

function Counter() {
    
    
  const [count, setCount] = useState(0);

  useEffect(() => {
    
    
    const id = setInterval(() => {
    
    
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(id);
  }, []);

  return <h1>{
    
    count}</h1>;
}
  1. What is the count output? Why? How to modify?
    It changes from 0 to 1 and then remains unchanged. Because the dependency array is empty, it is only executed once. If
    you want count+1 per second, you can write count in the dependency array.

Code question
new Array(100).map((_, i) => i); What does it return?
Array with length 100 and no elements

Please create an array with a length of 100 and store [0,1,2,…,99]
const arr = […Array(100)].map(( , i) => i);
Array(100) .fill().map((
, i) => i)

How to determine whether an event can bubble?
Each event has an event.bubbles attribute, through which you can know whether it bubbles.
Price is the price of the hotel, and score is the score of the hotel. The hotels are sorted according to the following strategy:
first sort by price from low to high, and when the prices are equal, Sort by rating from high to low
Codes

 const a={
    
    
    hotels: [{
    
    
        id: 1,
        price: 100,
        score: 80
    }, {
    
    
        id: 2,
        price: 70,
        score: 90, 
    }, {
    
    
        id: 3,
        price: 70,
        score: 95
    }]
}
a.hotels.sort((a,b) => {
    
    
    if (a.price === b.price) {
    
    
        return b.score-a.score
    } else {
    
    
        return a.price - b.price
    }
})

console.log(a)

Cookie and session mechanism

The functional effects of Session and Cookie are similar. The difference is that session is recorded on the server side, and cookie is recorded on the client side. They all record a series of states.
Combining: Put the session ID in the cookie (why use cookies to store it? Because cookies are temporary and scheduled. Temporary means that it disappears when the current browser is closed, which means that the session is originally used when browsing. It disappears when the browser is closed, so it can be stored in a temporary cookie. The session ID in the cookie will not be repeated after it is saved, because it is unique.), when the browser is allowed to use cookies, the session will depend on cookies. When browsing If the server does not support cookies, you can obtain the data resources in the session memory through the second method.
Insert image description here

Will the absolute element be position: fixedpositioned relative to the set element?
Answer:
Elements with postion: absolute; will be positioned relative to the first parent element whose value is not static.

xhr.abort() cancels sending ajax request

promise value penetration

The parameters of .then or .catch are expected to be functions, and value penetration will occur if non-functions are passed in.
Promise method chains pass values ​​through return. Without return, they are just independent tasks.
1

Promise.resolve('foo').then(Promise.resolve('bar')).then(function (result) {
    
      console.log(result);});

2

Promise.resolve(1)
  .then(function(){
    
    return 2})
  .then(function(){
    
    return Promise.resolve(3)})
  .then(console.log)

3

Promise.resolve(1)
  .then(function(){
    
    return 2})
  .then(Promise.resolve(3))
  .then(console.log)

From the onion model,
you can see that in order to pass through the center point of the onion, you must first penetrate the onion skin layer by layer into the center point, and then penetrate the skin layer by layer outward from the center point. There is a characteristic here: when entering How many layers of skin have been penetrated, how many layers of skin must be penetrated when exiting. Penetrating the epidermis first and then exiting it conforms to the principle of what we call a stack list, first in, last out.
Insert image description here

Features of floating & inline block elements

First of all, if the width of the inline block element is not set, it will not inherit 100% of the parent. You need to manually set the
floating element to have the characteristics of the inline block. Setting the floating element will only affect the standard flow of the element behind it, and will not affect the element in front of it. layout.

How to solve the problem of empty gaps after setting inline-block elements side by side?

Method 1 : Set the font-size of the parent element to 0, and set the font size of the child element separately.

Code question

const bbb = {
    
    
    abc:1
}

function a(o) {
    
    
    const f = function () {
    
     }
    f.prototype = o
    return  new f()
}
const bb = new a(bbb)
//12行是往bb实例上添加abc属性,不会去改变原型的abc就被拦截了
bb.abc = 2;
console.log(bbb,bb)

css implements elements with fixed aspect ratio

1. When the width and height of ordinary elements are unknown, without css, we can think of using js to get the width or height of the element in real time, and then calculate another value according to the ratio. Using css requires a little skill. In general Just use padding to increase the height. The code is as follows:

<div class="mainWrap">
    <div class="main"></div>
</div>

css:
.mainWrap {
    width: 20vw;
}
.main {
    width: 100%;
    padding-bottom: 75%;
    background: black;
}

2. Use aspect-ratio. This CSS attribute is specially used to set a fixed aspect ratio. However, you need to pay attention to the browser compatibility when using it.

Code question:

console.log(['1','2','3'].map(parseInt))//1 NAN NAN

So the actual code executed is:

['1', '2', '3'].map((item, index) => { return parseInt(item, index) }) The returned values ​​are:


parseInt('1', 0) // 1
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN, 3 is not binary

Guess you like

Origin blog.csdn.net/wyh666csdn/article/details/131033397