preface
- Now front-end interview often encounter strange questions, some have never heard of, how can you answer correctly, these are small friends submitted questions, everyone take a look, these questions are excellent, want to get a satisfactory offer, have to answer ah, a headache
Why is typeof NULL object
-
Null creates a bug. According to type tags, the low value is 000, so NULL is judged to be an object. That is why the return value of typeofNULL is “object”.
-
About the type of null in MDN document also has a simple description: typeof – Java | MDN
-
There was a proposal in ES6 to fix this bug, which stated that typeofNULL ===’null’wiki.ecma.org/doku.php?id… The proposal was ruthlessly rejected, and typeofNULL is finally not a bug, but a feature, and will never be fixed
Why and how does 0.1+0.2 not equal 0.3
- Problems like this are encountered during development:
Let n1 = 0.1, n2 = 0.2 console.log(n1 + n2) // 0.30000000000000004Copy the code
- This is not the desired result. To equal 0.3, we need to transform it:
(n1 + n2). ToFixed (2) // Note that toFixed is roundedCopy the code
The toFixed(num) method rounds the Number to a specified decimal Number. So why did this happen?
Computers store data in binary format, so when a computer computes 0.1+0.2, it actually computes the binary sum of two numbers. The binary of 0.1 is 0.0001100110011001100… (1100 loop), 0.2 binary is: 0.00110011001100… (1100 cycles), the binary of both numbers are infinite cycles. So how does JavaScript handle an infinite loop of binary decimals?
We generally think of numbers as integers and decimals, but there is only one Number type in JavaScript: Number, which is implemented in accordance with IEEE 754 standards and is represented as a 64-bit fixed length, the standard double floating-point double. In binary scientific notation, the decimal part of a double-precision floating-point number can be reserved at most 52 digits, plus the 1 in front of it, which is actually 53 significant digits. The rest must be discarded, following the principle of “rounding zeros into ones”.
According to this principle, the binary numbers of 0.1 and 0.2 are added and converted to decimal: 0.30000000000000004.
Here’s how doubles are saved:
- The first part (blue) : used to store sign bits, used to distinguish positive and negative numbers, 0 represents a positive number, occupying 1 bit
- The second part (green) is used to store exponents, occupying 11 bits
- The third part (red) is used to store decimal numbers
For 0.1, its binary is:
0.00011001100110011001100110011001100110011001100110011001 10011...
Copy the code
Convert to scientific notation (scientific notation results in floating point numbers) :
1.1001100110011001100110011001100110011001100110011001 * ^ 2-4Copy the code
It can be seen that the sign bit of 0.1 is 0, the exponential bit is -4, and the decimal bit is:
1001100110011001100110011001100110011001100110011001
Copy the code
So the question is, how do I store the negative digits?
The IEEE standard specifies an offset that is added to the exponential part each time, so that even if the exponential is negative, the offset is added to the positive number. Because JavaScript numbers are doubles, here we take the double as an example, its exponential part is 11 bits, can represent the range is 0 to 2047, IEEE fixed double offset is 1023.
- When the index bits are not all zeros and not all ones (normalized values), IEEE provides that the formula for calculating the order code is e-bias. In this case, the minimum value of E is 1, then 1-1023= -1022, and the maximum value of E is 2046, then 2046-1023=1023. It can be seen that in this case, the value range is
- 1022 ~ 1013
. - When all the index bits are 0 (the normalized value), IEEE defines the calculation formula of the order code as 1-bias, that is, 1-1023= -1022.
- When all the exponent bits are 1 (special value), IEEE specifies that this floating-point number can be used to represent three special values, which are plus infinity, minus infinity, and NaN. Specifically, NaN is represented when the decimal place is not zero; When the decimal place is 0, the sign bit s=0 represents positive infinity, and s=1 represents negative infinity.
For the index bit of 0.1 above is -4, -4+1023 = 1019 is converted to binary: 1111111011.
Therefore, 0.1 is expressed as:
0, 1111111011, 1001100110011001100110011001100110011001100110011001Copy the code
Having said that, it’s time to start with the question: how do 0.1+0.2=0.3?
A straightforward solution to this problem is to set a margin of error, often referred to as “machine accuracy.” For JavaScript, this value is usually 2-52. In ES6, the Number.EPSILON attribute is provided, and this value is 2-52. 0.1+0.2 ===0.3
function numberepsilon(arg1,arg2){
return Math.abs(arg1 - arg2) < Number.EPSILON;
}
console.log(numberepsilon(0.1 + 0.2, 0.3)); // true
Copy the code
Why use weakMap
-
WeakMap is a weak reference, which is good for garbage collection.
-
Once the node is removed from reference, its memory is freed by the garbage collection mechanism. The key value pair saved by Weakmap will also disappear automatically.
-
In short, the special occasion of WeakMap is that the object corresponding to its key may disappear in the future. The WeakMap structure helps prevent memory leaks.
What are RAF and RIC
- RequestAnimationFrame: tells the browser to execute the incoming callback function (usually manipulating the DOM, updating the animation) before the next redraw Since it is executed once per frame, this results in the same number of executions per second as the number of browser screen refreshes, usually 60 per second.
- RequestIdleCallback: : performs callbacks during browser idle time, which allows developers to perform low-priority tasks in the main event loop without affecting some later-critical events. If there are multiple callbacks, they are executed on a first-in, first-out basis, but when timeout is passed, it is possible to shuffle the order to avoid timeouts.
Escape, encodeURI, encodeURIComponent
- EncodeURI escapes the entire URI, converting illegal characters in the URI to legal characters, so characters that have special meaning in the URI are not escaped.
- EncodeURIComponent escapes URI components, so special characters can be escaped as well.
- Escape and encodeURI have the same effect, but they are different for unicode encoding characters other than 0xFF. Escape prefixes the character’s Unicode encoding with %u, EncodeURI first converts characters to UTF-8 format and prefixes each stanza with %.
Await what exactly is waiting for
What is await waiting for? “Await” is generally considered to be waiting for an async function to complete. But syntactically, await is an expression that evaluates to a Promise object or some other value (in other words, without special qualification).
Since an async function returns a Promise object, await can be used to wait for the return value of an async function — it can also be said to await an async function, but be clear that it is waiting for a return value. Note that await is not just used to wait for promises, it can wait for the result of any expression, so await is actually followed by ordinary function calls or direct quantities. So the following example works perfectly:
function getSomething() {
return "something";
}
async function testAsync() {
return Promise.resolve("hello async");
}
async function test() {
const v1 = await getSomething();
const v2 = await testAsync();
console.log(v1, v2);
}
test();
Copy the code
The result of an operation on an await expression depends on what it is waiting for.
- If it waits for something other than a Promise object, the result of the await expression operation is what it waits for.
- If it waits for a Promise object, await is busy and blocks the following code, waiting for the Promise object resolve, and then getting the value of resolve as the result of the await expression.
Here’s an example:
function testAsy(x){ return new Promise(resolve=>{setTimeout(() => { resolve(x); }, 3000) } ) } async function testAwt(){ let result = await testAsy('hello world'); console.log(result); // Hello world console.log('cuger') // Cug} testAwt(); Console. log('cug') // Output cug immediatelyCopy the code
This is why await must be used in async functions. Async function calls do not block, and all blocking within them is wrapped up in a Promise object and executed asynchronously. Await suspend execution of current async, so ‘cug” output first, hello world’ and ‘cuger’ are 3 seconds later.
| | and && operator return values
- && and | | first judgment can be carried to the first operand condition, if it is not a Boolean value is the mandatory converted to Boolean type, and then execute condition judgment.
- For | |, if the condition judgment result to true will return the value of the first operand, if to false will return the value of the second operand.
- &&, on the other hand, returns the value of the second operand if true or the value of the first operand if false.
- && and | | return values of them one of the operands, and unconditioned judgment result
2 = = [[[2]]]
- According to the ES5 specification, if one of the two values being compared is of numeric type, an attempt is made to cast the other value to a number and then compare it. Casting an array to a number calls its toString method to a string, and then to a number. So [2] will be converted to “2”, then recursively called, and finally [[[2]] will be converted to the number 2.
var x = [typeof x, typeof y][1]; typeof typeof x; //”string”
-
Typeof y returns “undefined” because y is not declared.
-
Assign the result of typeof y to x, that is, x is now “undefined”
-
And then typeof X is of course “string”
-
The result of typeof “string” is of course “string”
Can you handle working overtime? And we don’t pay for overtime!
- F selections selections selections selections selections k y * * * * * * * * * * u
- Click to join the 6 o ‘clock clock