preface

If you don’t think it works, you’re welcome to beat the rabbit.

1. Optional parameters of parseInt() and toString()

ParseInt (string, radix) Radix optional. Represents the radix of the number to be parsed. The value is between 2 and 36.

If this parameter is omitted or its value is 0, the number is parsed on the basis of 10. If it starts with “0x” or “0x”, it will be based on 16. If this parameter is less than 2 or greater than 36, parseInt() returns NaN.

eg:
parseInt('10'.2);    // 1*2^1 + 0*2^0 = 2
parseInt('17'.8);    // 1*8^1 + 7*8^0 = 15
parseInt('1f'.16);   // 31 1*16^1 + 15*16^0 31
parseInt('0x12');     // 1*16^1 + 2*16^0 = 18
Copy the code

Number. ToString (radix) Radix optional. Specifies the cardinality of a number. It is an integer between 2 and 36. If this parameter is omitted, the cardinality 10 is used. Note, however, that if the parameter is a value other than 10, the ECMAScript standard allows the implementation to return any value.

eg:
var num = 15;
num.toString(2);    // 1111 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 15
num.toString(8);    // 1*8^1 + 7*8^0 = 15
num.toString(16);   // f in hexadecimal form f is 15 (0~9, A~ f)
Copy the code

2. 1. ToString () is an error, why not print “1”?

var num = 1;
num.toString();  / / "1"
Number(1).toString();   / / "1"
1.toString();    // Uncaught SyntaxError: Invalid or unexpected token
1.0.toString();  / / "1"
1..toString();   / / "1"
1 .toString();   / / "1"
Copy the code

Why: When a dot follows a number it means that the number is a floating point number, and after the dot JS waits for a number. So before calling toString(), we need to tell JS that this is the number we want. ToString () is a primitive type, so there is no toString() method. ToString () is a wrapper type, so there is no error.

3. Why 0.1+0.2=0.30000000000000004?

Answer: For a computer, two numbers are added in binary form and converted to decimal form when the result is rendered. This result is due to the loss of accuracy in the process of conversion, the solution is to convert to integer operation and then reduce, of course, for complex, you can introduce third-party libraries (bignumber.js, etc.).

Number.MAX_VALUE;   / / 1.7976931348623157 e+308
Number.MIN_VALUE;   // 5e-324
Copy the code

4. The second argument to the usual iteration method for arrays

The iterating methods are every(), filter(), forEach(), map(), some(), find(), findIndex(). All of these methods take the same parameters, using forEach() as an example:

array.forEach(function(currentValue, index, arr), thisValue)

ThisValue optional. The value passed to the function is usually the “this” value. If this parameter is empty, “undefined” is passed to the value “this”

eg:
function run(param) { 
    console.log( param, this.id ); 
}
var obj = { 
    id: "welcome"
}; 
[1.2.3].forEach( run, obj );  // 1 "welcome" 2 "welcome" 3 "welcome"
Copy the code

If you need to display the binding this in an iteration, consider the second argument.

5. Array’s most overlooked reduce() method

Array. reduce(function(Total,currentValue, ArR), initialValue) ① Function (Total,currentValue, Index, ARR)

  • The total required. The initial value, or the return value at the end of the calculation.
  • CurrentValue required. The current element
  • CurrentIndex optional. The index of the current element
  • Arr is optional. The array object to which the current element belongs.

(2) the initialValue is optional. The initial value passed to the function

Nifty – Count the number of occurrences of each character in a string, the most concise code:
var str = 'welcome to my world';
var obj = {};
[...str].reduce((prev, cur) = >{
    obj[cur] ? obj[cur]++ : obj[cur] = 1;
}, {})
console.log(obj);   // {" ": 3,c: 1,d: 1,e: 2,l: 2,m: 2,o: 3,r: 1,t: 1,w: 2,y: 1}
Copy the code

6. Understand arrays are special objects

Define an array in the form of an object, as follows:

var arr = {
    0: 1.1: 2.2: 3.length: 3
}
arr[0];     / / 1
typeof arr;     // "object"
Copy the code

Arrays are special objects that can naturally be added with attributes:

var arr = [1.2.3];
arr.md = 'well';
arr.length;     / / 3
arr.md;         // "well"
/ / attention
arr["2"] = 4;   // There are quotes here. Essentially, even if there are no quotes here, it will be converted to a string first, because the key of the object can only be a string
arr[2];     / / 4
Copy the code

7. Empty space in the array

From ({length: 3}), and array. apply(null, {length: 3}). All previous methods were more or less problematic. Let’s look at it in code:

Array.from({length: 3});    // [undefined, undefined, undefined]
Array(3);   // [empty × 3] = [,,,]
Array(1.2.3);     / / [1, 2, 3]
Copy the code

Corresponding to the above 3 ways, I write in the form of objects to help you understand:

{0: undefined.1: undefined.2: undefined.length: 3}
{length:3}
{0: 1.1: 2.2: 3.length: 3}
Copy the code

So array. from({length: 3}) is equivalent to array. from(Array(3)). In the second way, the array is empty. The second and third methods show the behavior of Array() depending on the number of parameters. Of course, ES6 provides a solution for array.of (). We focus on the vacancy:

  • ES5 is very inconsistent in its handling of vacancies, which are ignored in most cases.
  • ForEach (), filter(), reduce(), every() and some() all skip empty Spaces
  • Map () skips the empty space but keeps the value
  • Join () and toString() treat empty Spaces as undefined, while undefined and null are treated as empty strings
  • ES6 explicitly converts a vacancy toundefined
  • The array. from method converts an Array void to undefined
  • Extended operators (…) Will change the empty space to undefined
  • CopyWithin () copies the empty space
  • Fill () treats the empty space as a normal array position
  • for… The of loop also iterates over the empty space
  • Entries (), keys(), values(), find() and findIndex() treat empty Spaces as undefined

As you can see, the rules for handling empty Spaces are very inconsistent, so it is recommended to avoid empty Spaces.

8. The difference between string interception methods slice(), substr(), substring()

The string. Slice (start,end) argument can be negative

Substr (start,length) The first argument can be a negative number and the second argument is a length string.substring(from, to) must all be non-negative integers

9. SetTimeout () third argument

Effect: The third argument is passed as an argument to the first function

Compare the following code to see what it does:
for(var i = 0; i<6; i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}               // Output 6 times 6
for(var i=0; i<6; i++){setTimeout(function(j){
        console.log(j);
    },i*1000,i);
}               // Outputs 0 to 5 in sequence, with an interval of one second
Copy the code

10. Do you really know the && operator in Javascript?

  • If the first operand is an object, return the second operand;
  • If the second operand is an object, it is returned only if the first operand evaluates to true

Object;

  • If both operands are objects, return the second operand;
  • Return null if one of the operands is NULL;
  • If one of the operands is NaN, NaN is returned;
  • Returns undefined if one of the operands is undefined.
Good idea: You can read this one of mineUnderstanding: Conditional Object Properties

11. Do you really understand the + operator in Javascript?

undefined + undefined;      // NaN (Not a Number)
undefined + null;           // NaN
1 + null;                   // 1: Number(null) returns 0 isNaN(null) === false
1 + undefined;              Number(undefined) returns NaN isNaN(undefined) === true
'1' + null;                 // "1null"
'1' + undefined;            // "1undefined"
'1' + 1;                    / / "11"
1 + [1]                     [1].toString() === "1"
1+ {a:1}                    // "1[object Object]"
Copy the code

In the “Additive operators” section of the book “javaScript Advanced Programming”, there are three detailed explanations:

  • If one of the operands is NaN, the result is NaN;
  • If only one operand is a string, the other operand is converted to a string, and then the two strings are concatenated

To get up.

However, if one of the operands is a string, the following rule applies:

  • If both operands are strings, concatenate the second operand with the first;
  • If only one operand is a string, the other operand is converted to a string, and then the two strings are concatenated

To get up.

  • If one of the operands is an object, a value, or a Boolean, their toString() method is called to get the corresponding string value.

Then apply the previous rules for strings. For undefined and null, call String() and get the strings “undefined” and “null”, respectively.

12. Do you know the difference between object.is () and ===?

  • The equality operator (==) automatically converts the data type
  • The strict equality operator (===) NaN does not equal itself, and +0 equals -0
Seeing is believing:
1= ='1';       // true
1= = ='1';      // false
NaN= =NaN;     // false
NaN= = =NaN;    // false
+0= = -0;       // true
+0= = = -0;      // true
null= =undefined;      // true
null= = =undefined;     // false
Copy the code

Object.is() differs from this:

  • Plus 0 is not equal to minus 0
  • NaN equals itself
Object.is(+0, -0);     // false
Object.is(NaN.NaN);   // true
Copy the code

13. Object.create(null) differs from {}

Object.create(proto[, propertiesObject]) :

Proto Prototype object of the newly created object propertiesObject Optional. If undefined, it is the property descriptor of the non-enumerable (default) property to be added to the newly created object (that is, the property it defines itself, not the enumerated property on its stereotype chain) and the corresponding property name. These properties correspond to the second argument to Object.defineProperties()

The return value:

A new object with the specified prototype object and properties.

Object.create(null) sets the prototype of the returned new Object to NULL. Compared to {}, it does not have Object prototype methods such as toString(). It is cleaner, safer, and often useful as an empty Object. Object. Create (null); Object. Create (null);

14. Traversal of ES6 attributes and traversal rules

  • for… in

for… The in loop iterates over the object’s own and inherited enumerable properties (excluding the Symbol property).

  • Object.keys(obj)

Keys returns an array containing the key names of all of the Object’s own (not inherited) enumerable properties (not including the Symbol property).

  • Object.getOwnPropertyNames(obj)

Object. GetOwnPropertyNames returns an array containing all attributes of the Object itself (excluding Symbol attribute, but cannot be enumerated attribute) of keys.

  • Object.getOwnPropertySymbols(obj)

Object. GetOwnPropertySymbols returns an array containing all the Symbol attribute of the Object itself the key name.

  • Reflect.ownKeys(obj)

Reflect.ownKeys returns an array containing all of the object’s own (not inherited) key names, whether they are symbols or strings or enumerable.

Traversal rules:

First, all numeric keys are iterated, sorted in ascending order.

Next, all the string keys are iterated in ascending order by the time they were added.

Finally, all Symbol keys are iterated in ascending order of time they were added.

eg:
Reflect.ownKeys({ [Symbol()] :0.b:0.10:0.2:0.a:0 })
// ['2', '10', 'b', 'a', Symbol()]
Copy the code

15. Check if the object has a property (the in operator you ignored)

There are 3 ways:

  • if('key' in obj)Inheritance properties are checked
  • obj.hasOwnProperty('key')Only examine its own properties
  • if(obj.key)Because of the stereotype chain mechanism, inheritance properties are detected (forifFor implicit conversions, see title 16.)

Caution: Use the third method with caution, as it may not work as expected. For example:

var myObject = { 
    a: undefined
};
myObject.a; // undefined 
myObject.b; // undefined
Copy the code

16. Implicit type conversion in if Boolean()

The data type The value converted to true Convert to a value of false
Boolean true false
String Any non-empty string “”(empty string)
Number Any non-zero numeric value (including infinity) 0 and NaN
Object Any object null
Undefined Do not apply undefined
### 17. What to note about the built-in function Date()
  • new Date().getDay()It returns a day of the week
  • new Date().getDate()It returns a day in the middle of January

Tips: Confusion about this is common in development

18. Three ways to achieve object deformation and their differences

  • Object.preventextensions () disables extension

Disallows an object to add new attributes and retain existing attributes, which can be deleted

  • Object. The seal ()

This method actually calls Object.preventExtensions() on an existing Object and marks all existing properties as Signals :false.

Therefore, not only can you not add new attributes after sealing, you can’t reconfigure or delete any existing attributes (although you can change their values).

  • Object. Freeze (freeze)

This method actually calls Object.seal() on an existing Object and marks all “data access” properties as writable:false, so that their values cannot be changed.

This method is the highest level of immutability you can apply to an object, and forbids modification of the object itself or any of its immediate properties

Of course, there are corresponding methods to remove invariance, which will not be introduced here.

19. Shallow and deep copies

Both shallow and deep copies are relative to reference types such as Object and Array because they make no sense to base types

Memory storage of reference type data
Stack memory Heap memory
name val val
obj Heap address (value pointing to heap memory) {a: 1,b: 2… }

A shallow copy is a copy of the heap address, while a deep copy is a copy of the heap memory. Therefore, after the shallow copy, the modification of any variable value will be reflected in the other variable, which will affect each other, but the deep copy will not.

Shallow copy can be implemented by:

  • Common assignment operations
var a = [1.2.3];     
var b = a;
b[2] = 4;
console.log(a[2]);      / / 4
Copy the code
  • Object.assign()
var obj = {
    a: 1.b: 2
}
var obj1 = Object.assign(obj);
obj1.a = 3;
console.log(obj.a) / / 3
Copy the code

How to implement deep copy (excluding third-party libraries) :

  • Using JSON serialization
var obj = {
    a: 1.b: 2
}
var obj1 = JSON.parse(JSON.stringify(obj));
obj1.a = 3;
console.log(obj.a);     / / 1
Copy the code
  • Extended operator
var arr = [1.2.3];
var arr1 = [...arr];
arr1[2] = 4;
console.log(arr[2]);    / / 3
Copy the code
  • For deep copies of arrays, in addition to extending the operators, you can also take advantage of the array’s own methodsSlice, concat () ()

Note: Both slice() and concat() return a new array copy

  • For deeply nested complex objects, recursive assignment is adopted
function deepCopy(a, b= {}) {
    for(let item in a){
        if(typeof a[item] === "object"){
            b[item] = {};
            deepCopy(a[item], b[item]);
        }else{ b[item] = a[item]; }}return b;
}
var a = {
    x: 1.y: {
        z: 2}}var b = deepCopy(a);
a.y.z = 4;
console.log(b.y.z);    // the value of the property in b does not change, indicating a deep copy
Copy the code

20. Parameters are passed as “value”

Explanation: When passing a parameter, whether it is a primitive type or a reference type, follow the principle of “value”. Copy the external value of the function and assign the value of the copy to the internal parameter.

  • Basic type parameter: The copied value is the basic type
  • Reference type parameter: The copied value is an in-memory address reference, which can be understood as a pointer to
Here’s an example from a previous blogger:
var type = 'images';
var size = {width800.height600};
var format = ['jpg'.'png'];
function change(type, size, format){
    type = 'video';
    size = {width1024.height768};
    format.push('map');
}
change(type, size, format);
console.log(type, size, format);    // 'images', {width: 800, height: 600}, ['jpg', 'png', 'map']
Copy the code

21. Execution efficiency of for, forEach(), map()

for > forEach() > map()

Reason: forEach() and map() traversals need to maintain the current item and index, and are necessarily slower than for. Map () allocates memory to store a new array and returns it. ForEach () does not return data, so map() is the slowest.

22. Where else can the super keyword be used except in the constructor of an inherited class?

  • When inheriting, super() in the subclass constructor means calling the parent class’s constructor, returning the instance of the subclass. The this inside super() refers to an instance of a subclass, so super() is equivalent in the subclass constructorParentClass. Prototype. Constructor. Call (this).
  • When super is an object, in a normal method, it points to the prototype object of the parent class
    class A {}
    A.prototype.x = 2;
    
    class B extends A {
      constructor() {
        super(a); }print(){
        console.log(super.x); }}var b = new B();
    b.print();      / / 2
Copy the code
  • In static methods, point to the parent class
    class A {       // The example of Teacher Ruan
      constructor() {
        this.x = 1;
      }
      static print() {
        console.log(this.x); }}class B extends A {
      constructor() {
        super(a);this.x = 2;
      }
      static m() {
        super.print();  
        // When a static method of a subclass is called through super, the this inside the method refers to the current subclass, not the instance of the subclass
      }
    }
    
    B.x = 3;
    B.m() / / 3
Copy the code

23. Object and array conversions

Make good use of the Object.fromentries () and object.entries () methods.

Object.fromEntries([
  ['x'.1],
  ['y'.2]])// { x: 1, y: 2 }
Copy the code
var arr = Object.entries({x: 1.y: 2});
console.log(arr);   // [['x', 1], ['y', 2]]
Copy the code

After converting an object to an array, you can also use the array flat function to flatten it out:

var arr = [['x'.1], ['y'.2]];
arr = arr.flat();
console.log(arr);   // ["x", 1, "y", 2]
Copy the code

Here’s another way to convert a one-dimensional array to an arbitrarily dimensional array:

function translate(num, arr) {  // num: the dimension you want to convert, arr: the initial array
  const newArr = [];
  while(arr.length > 0) {
    newArr.push(arr.splice(0, num));
  }
  return newArr;
}
translate(2[1.2.3.4]);     / / [[1, 2], [3, 4]]
Copy the code

About 24.JSON.stringify()

For most simple values, JSON stringalization has the same effect as toString(), except that the result of serialization is always a string:

JSON.stringify( 42 ); 42 "/ /"
JSON.stringify( "42" ); // ""42"" (string with double quotes)
JSON.stringify( null ); // "null"
JSON.stringify( true ); // "true"
Copy the code

Json.stringify () automatically ignores undefined, function, and symbol when it encounters them in objects, and returns null in arrays (to ensure unit positions remain the same).

JSON.stringify( undefined ); // undefined
JSON.stringify( function(){});// undefined
JSON.stringify(
 [1.undefined.function(){},4]);// "[1,null,null,4]"
JSON.stringify(
 { a:2.b:function(){}});// "{"a":2}"
Copy the code

Executing json.stringify () on an object that contains a circular reference will cause an error. If the toJSON() method is defined on the object, it is first called when the JSON is stringed, and then its return value is used for serialization. Json.stringify () The second optional argument, replacer, can be an array (which must be an array of strings) or a function (which takes two arguments, a key and a value) that specifies which properties should be processed and which should be excluded during object serialization.

var a = { 
 b: 42.c: "42".d: [1.2.3]};JSON.stringify( a, ["b"."c"]);// "{"b":42,"c":"42"}"
JSON.stringify( a, function(k,v){
 if(k ! = ="c") returnv; });/ / "{" b" : 42, "d" : [1, 2, 3]}"
Copy the code

The third optional argument, space, specifies the indentation format for the output. Space is a positive integer that specifies the number of characters to indent at each level. It can also be a string,

JSON.stringify( a, null."-- -- -- -- --" );
{/ /"
// -----"b": 42,
// -----"c": "42",
// -----"d": [
/ / -- -- -- -- -- -- -- -- -- - 1,
/ / -- -- -- -- -- -- -- -- -- -- 2,
/ / -- -- -- -- -- -- -- -- -- -- 3
/ / -- -- -- -- --
// }
Copy the code

25. Public string and array methodsincludesThe attention of the points

The includes method for strings shows subtle differences when handling numbers:

[1.2.3].includes('1');    // false
['1'.'2'.'3'].includes(1);    // false
'123'.includes('1');    // true
'123'.includes(1);      // true
Copy the code

You can see that. Also note that the comparison method inside the includes method is neither strict equality (===) nor object.is (). You can think of it as adding a NaN equals NaN condition to strict equality (===). Or add a condition that positive and negative zeros are equal to object.is (). See the examples:

[+0.NaN].includes(-0);     // true
[+0.NaN].includes(NaN);    // true
// ------- to help you remember strict equality with object.is ()------
+0= = = -0;  // true
NaN= = =NaN;    // false
Object.is(+0, -0);  // false
Object.is(NaN.NaN);  // true
Copy the code

26. Bitwise and&The use of

If you were asked to determine whether a number is two to the NTH power, what would you do? Consider bitwise operations, which can be implemented by subtracting themselves.

var number = 16
(number & number -1) = = =0 // true
Copy the code

Principle: just a conclusion derived from the law. Looking at the numbers below, we see that the binary values are always opposite to each other in relative positions. The result of the & operation must be 0.

The decimal system binary
8 1000
7 0111
16 10000
15 01111

Swap the values of two variables

[y, x] = [x, y] can be easily implemented by using deconstructive assignment in ES6. In ES5 we usually use intermediate variables, but there is another way to do this:

var a = 4,b = 3
a = a ^ b  / / 7
b = a ^ b  / / 4
a = a ^ b  / / 3
Copy the code

Just to show you how useful the xor ^ operator can be.

28. Integer

  • Math.floor()Take down the whole
  • Math.ceil()Take up the whole
  • toFixed(0)rounded
  • parseInt()It intercepts only integer bits and returns if it cannot be parsedNaN
  • ~ ~Truncated integer bits, no returnNaNIn the case
~ ~'1.2 how are you' / / 0~ ~'1.2' / / 1~ ~'1.7' / / 1~ ~null / / 0~ ~undefined / / 0~ ~NaN / / 0
Copy the code

The essence of the ~ bitwise nonoperator is to return the inverse of a numeric value. Remember that ~x === -x-1:

var num1 = 25;    / / binary 00000000000000000000000000011001
var num2 = ~num1; / / binary 11111111111111111111111111100110
console.log(num2); / / - 26
Copy the code

29. Thousand-character separator

The previous requirement was to reverse the string, insert commas every three bits, and reverse it back again. For example: 1234567890 => 0987654321 => 098,765,442,1 => 1,234,567,890 Instead, I use a regular line:

"1234567890".replace(/\B(? = (? :\d{3})+(? ! \d))/g,",") // Result:"Copy the code

A less recommended alternative is toLocaleString:

NumberObject. ToLocaleString () returns a value: a string representation of the digital, decided by the implementation, according to local standard format, may affect the decimal point or micrometer delimiter used punctuation marks.

1234567890..toLocaleString() // Result: "1,234,567,890"
Copy the code

30. Call and apply

In non-strict mode, the first parameter of call and apply is:

  • fornull 或 undefinedIs automatically replaced with pointing to a global object
  • Is wrapped when it is the original value
function a () {
  console.log(this.'a');
}

a.call('b'); // String {"b"} "a"
Copy the code

Strict mode:

'use strict'
function a () {
  console.log(this.'a');
}

a.call('b'); // b a
Copy the code

Strange:

function a () { 
  console.log(this.'a')};function b () {
  console.log(this.'b')
}
a.call.call(b, 'b')  // String {"b"} "b"
Copy the code

conclusion

Do you have a lot of question marks when you see the titles one by one?? If so, the proof base needs to be strengthened.

In the future, I will definitely see or think of knowledge points that students do not pay much attention to. This article will be updated irregularly.