Front-end development engineer--js interview questions-concept articles

Base

Common array methods are those, those will change the original array

How to change the original array

  1. push : add at the end of the array
  2. pop : delete at the end of the array
  3. unshift : add at the head of the array
  4. shift: delete at the head of the array
  5. splice: delete/add elements at specified positions
  6. fill : fill the array
  7. forEach: Loop each item, similar to a for loop
  8. reverse : reverse the array
  9. sort: sort

Methods that don't mutate arrays

  1. slice: intercept the element at the specified position
  2. concat: join two arrays
  3. filter: filter the array according to the condition
  4. find : According to the addition, return the first element that matches the addition
  5. map: Process each element of the array through the specified function and return the processed array.

Several data types of js

  1. basic data type

string number boolean undefined null

  1. referential data type

object array

The method of judging the type

  1. typeof xx: Only basic types and reference types can be judged
console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object     注意
console.log(typeof function(){
    
    });    // function 
console.log(typeof {
    
    });              // object 
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object     注意

2. instanceof can correctly judge the type of object, and its internal operation mechanism is to judge whether the prototype of this type can be found in its prototype chain.

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

3.Object.prototype.toString.call() uses the prototype method toString of the Object object to determine the data type:

var a = Object.prototype.toString;

console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){
    
    }));
console.log(a.call({
    
    }));
console.log(a.call(undefined));
console.log(a.call(null));

Principle:
the detection object obj calls the toString method, the result of obj.toString() is different from the result of Object.prototype.toString.call(obj), why?
This is because toString is the prototype method of Object, and types such as Array and function are instances of Object , and the toString method is rewritten. When different object types call the toString method, according to the knowledge of the prototype chain, the corresponding rewritten toString method is called (the function type returns a string whose content is the function body, and the Array type returns a string composed of elements...), while It will not call the prototype toString method on Object (returns the specific type of the object), so the object type cannot be obtained by using obj.toString(), and obj can only be converted to a string type; , the toString method on the Object prototype should be called.

when will x of if(x) be true

false :
'' , false , 0 , -0 , null ,undefined , NaN
true :
' '(with spaces inside), 'str' , 123 , [] , {} ,

Priority of variable hoisting and function hints

function > variable
new Doo() > new Doo > Doo()

The difference between null and undefined

First of all, Undefined and Null are both basic data types, and each of these two basic data types has only one value, which is undefined and null.
The meaning of undefined is undefined, and the meaning of null is an empty object. Generally, when a variable is declared but not yet defined, it will return undefined, and null is mainly used to assign to some variables that may return objects as initialization .
undefined is not a reserved word in JavaScript, which means that you can use undefined as a variable name, but this approach is very dangerous, it will affect the judgment of undefined value. We can get safe undefined value through some methods, such as void 0.
Null typing returns "object" when using typeof on these two types, which is a legacy issue. Returns true when using a double equals sign to compare two types of values, and returns false when using triple equals signs.

Why 0.1+0.2 ! == 0.3 and how to make it equal

Double precision problem
(n1 + n2).toFixed(2) // Note that toFixed is rounded

The difference between var let const

  1. Variable hoisting (var is hoisted to the very top of the scope)

let const has no variable promotion, var has.
For example,
a variable defined by var can be defined after use
a = 10;
var = a;
the compiled code is
var a =undefined
a = 10

  1. temporary dead zone
    c= 10     //这块区域就是暂时性死区
    let c
    console.log(c);  //  ReferenceError:
  1. Cannot repeat statement

var can be declared repeatedly, let const can't, and an error will be reported

  1. block scope works
  {
    
    
    var bb = 10
  }
  console.log(bb);    //10

  {
    
    
    let bb = 10
  }
  console.log(bb);  //ReferenceError: bb is not defined

this

  1. The this of ordinary functions points to Windows
       function a() {
    
    
           console.log('普通函数的this'+this);
       }
       a();//普通函数的this[object Window]
  1. The this of the arrow function defaults to the this point of the object in the context when it is defined. That is, the point of this in the ES6 arrow function is the point of the object this in the context. Occasionally, there is no context object, and this points to window
 let o = {
    
    
       name:'张三',
       say:()=>{
    
    
               console.log('箭头的this',this.name); //win   这里上下文没有函数对象就默认为window
         }
   }
  o.say();
  1. The this in the object points to whoever calls it
 let o = {
    
    
       name:'张三',
       say:function(){
    
    
               console.log(this.name); // 张三
         }
   }
  o.say();

The difference between arrow function and ordinary function

  1. Arrow functions are more concise than ordinary functions
  2. The arrow function does not have its own this.
    The this of the arrow function points to the scope where it is located. So the point of this in the arrow function has been determined when it is defined, and will not change afterwards.
  3. The this pointer inherited by the arrow function will never change
var id = 'GLOBAL';
var obj = {
    
    
  id: 'OBJ',
  a: function(){
    
    
    console.log(this.id);
  },
  b: () => {
    
    
    console.log(this.id);
  }
};
obj.a();    // 'OBJ'
obj.b();    // 'GLOBAL'
new obj.a()  // undefined
new obj.b()  // Uncaught TypeError: obj.b is not a constructor

对象obj的方法b是使用箭头函数定义的,**这个函数中的this就永远指向它定义时所处的全局执行环境中的
this**即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。
需要注意,定义对象的大括号{
    
    }是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中。
  1. Call(), apply(), bind() and other methods cannot change the direction of this in the arrow function
  2. Arrow functions cannot be used as constructors
  3. Arrow functions do not have their own arguments
  4. Arrow functions have no prototype

Event bubbling and event capturing in event streams

Event flow describes the order in which events are received by a page.
History: At the time, the IE and Netscape development teams at the two major companies came up with almost diametrically opposite approaches to event streaming. IE will support event bubbling streams, and Netscape Communicator will support event capturing streams.
Event bubbling: starting from the element bound to the event, and then propagating upwards to less specific elements

<!DOCTYPE html> 
<html> 
<head> 
 <title>Event Bubbling Example</title> 
</head> 
<body> 
 <div id="myDiv">Click Me</div> 
</body> 
</html>	
在点击页面中的<div>元素后,click 事件会以如下顺序发生:
(1) <div>
(2) <body>
(3) <html>
(4) document

Event capture means that the least specific node should receive the event first, and the most specific node should receive the event last.

click

Elements fire click events in the following order:

(1) document
(2) <html>
(3) <body>
(4) <div>

The DOM2 Events specification stipulates that the event flow is divided into 3 stages: event capture, reaching the target and event bubbling.
insert image description here

The difference between for in and for of

  1. for in traverses the key is the key. for of traverses the key is the value

  2. for in traverses objects/arrays with enumerable properties, and objects on the prototype chain will also loop. If you don't want to traverse the prototype method and property, you can judge it inside the loop. Use the hasOwnProperty() method to determine whether a property is an instance property of the object

    for of traverses an iterable object/array

  3. for in cannot traverse set map. for of can

Scope and scope chain

  1. Global scope (can be understood as window)
  2. Function scope
    The function scope declaration is zeroed inside the function, generally only fixed code fragments can be accessed
  3. Block-level scope
    Use the new let and const instructions in ES6 to declare block-level scope. Block-level scope can be created in a function or in a code block (code fragment wrapped by { })
  4. Scope chain
    Scope chain: Find the required variable in the current scope, but there is no such variable in this scope, then the variable is a free variable. If you can't find the variable in your own scope, go to the parent scope to search, and then search to the upper scope in turn , until you access the window object, it will be terminated. This layer-by-layer relationship is the scope chain.
    The role of the scope chain is to ensure the orderly access to all variables and functions that the execution environment has access to . Through the scope chain, you can access the variables and functions of the outer environment.

advanced

Object.assign and extension algorithm are deep copy or shallow copy, the difference between the two

let outObj = {
    
    
  inObj: {
    
    a: 1, b: 2}
}
let newObj = {
    
    ...outObj}
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}

let outObj = {
    
    
  inObj: {
    
    a: 1, b: 2}
}
let newObj = Object.assign({
    
    }, outObj)
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}

As you can see, both are shallow copies .
The Object.assign() method receives the first parameter as the target object, and all subsequent parameters as the source object. Then merge all the source objects into the target object. It modifies an object, thus triggering the ES6 setter.
When used with the spread operator (…), each value in the array or object is copied into a new array or object. It doesn't copy inherited properties or class properties, but it does copy ES6's symbols property

Prototype and prototype chain (with inheritance)

When we create an object, there will be a prototype attribute, which points to an object, also called a prototype object. When we instantiate an object, the __proto__ attribute of the instance also points to the object prototype. In this way, a chain comes out, if the object still has a father. The grandfather would then form a prototype chain. as the picture shows
insert image description here

Constructors and Ordinary Functions

  1. The calling method is different.
    Ordinary function calling method: directly call person();
    constructor calling method: need to use the new keyword to call new person();
  2. This is different.
    This in ordinary functions points to undefined in strict mode, and points to the window object in non-strict mode.
    The this of the constructor refers to the object instance it creates.
  3. The naming convention is different

Closure

A closure is a function that has access to variables in the scope of another function . The most common way to create a closure is to create another function within a function. The created function can access the local variables of the current function.

function a {
    
    
	let ka = '1';
	function b {
    
    
 	console.log(ka)
 }
 b()
}

Two purposes:
The first purpose of closures is to enable us to access variables inside the function outside the function. By using closures, variables inside the function can be accessed externally by calling the closure function externally. This method can be used to create private variables .

Another use of the closure is to keep the variable object in the function context memory , because the closure function retains the reference of the variable object, so the variable object will not be recycled.

what the new keyword does

(1) Create a new empty object first
(2) Set the prototype, and set the prototype of the object as the prototype object of the function.
(3) Let the this of the function point to this object, execute the code of the constructor (add properties 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.

function objectFactory() {
    
    
  let newObject = null;
  let constructor = Array.prototype.shift.call(arguments);
  let result = null;
  // 判断参数是否是一个函数
  if (typeof constructor !== "function") {
    
    
    console.error("type error");
    return;
  }
  // 新建一个空对象,对象的原型为构造函数的 prototype 对象
  newObject = Object.create(constructor.prototype);
  // 将 this 指向新建对象,并执行函数
  result = constructor.apply(newObject, arguments);
  // 判断返回对象
  let flag = result && (typeof result === "object" || typeof result === "function");
  // 判断返回结果
  return flag ? result : newObject;
}
// 使用方法
objectFactory(构造函数, 初始化参数);

js execution mechanism

  1. The conceptual
    js code is divided into synchronous code and asynchronous code.
    The synchronous task will enter the main thread, and the asynchronous task will enter the Event Table (event table). When the asynchronous task in the event table is completed, the callback function will be registered in the Event Queue (event queue). The tasks in the Event Queue will not be completed until all the main thread tasks are completed. The js parser will repeatedly check whether the main thread execution stack is empty, thus forming an Event Loop (event loop)

insert image description here
2. Task subdivision
Tasks can be further divided into macro tasks and micro tasks , which have a more detailed impact on the execution of js code. Macro tasks and micro tasks in asynchronous tasks will enter different Event Queue event queues, namely Event Queue can be divided into macro task queue and micro task queue.
setInterval will repeatedly register the callback function in the Event Queue according to the set time interval. If the main thread code executes for too long in a certain period of time, the callback function of setInterval may be blocked and executed together, and the set time interval cannot be maintained. If at this time If setInterval is used for animation, it will be reflected as Caton.
insert image description here

handwriting

Guess you like

Origin blog.csdn.net/work33/article/details/127124057