This article sorted out some front-end classic interview questions, with detailed explanation, involving JavaScript in many aspects of knowledge, full of dry goods ~ recommended collection reading
preface
If this article is helpful to you, ❤️ attention + like ❤️ to encourage the author, the article public number first, pay attention to the front of nanjiu first time to get the latest article ~
1. Talk about JavaScript data types and how they are stored
There are eight data types in JavaScript
There are seven basic data types:
Null, undefined, Boolean, Number, String,
New in ES6: Symbol represents a unique value
New in ES10: BigInt Specifies any large integer
A reference data type:
Object (essentially consisting of an unordered set of key-value pairs)
Includes function,Array,Date, and so on. JavaScript does not support the creation of any custom type of data, which means that all values in JavaScript are of one of the above 8 types.
storage
- Basic data types: they are directly stored in stack memory, occupy a small space and are of a fixed size. They are frequently used data.
- Reference data type: Stored in stack memory and heap memory at the same time, occupies a large space, size is not fixed. Reference data types store Pointers on the stack and values on the heap. When we assign an object value to another variable, we copy a pointer to the object, pointing to the same memory address.
Null and undefined
Similarities:
- Undefined and Null are both basic data types, and each of these basic data types has only one value, namely Undefined and Null
Difference:
-
Undefined means undefined, and null means empty objects.
-
Typeof null returns ‘object’, typeof undefined returns ‘undefined’
-
null= =undefined // true null= = =undefined // false Copy the code
-
Null is not an object, although typeof NULL outputs object, but this is a long-standing JS Bug. In the original version of JS, the 32-bit system was used. For the sake of performance, the type information of the variable was stored at a low level. The beginning of 000 represents an object, while null represents all zeros, so it was wrongly judged as object. Although the internal type determination code has changed, the Bug has persisted.
2. There are several ways to determine data types in JavaScript
typeof
typeof
Generally used to determine basic data types,All is true except that null will output “object”typeof
When determining the reference data type,Except for “function”, everything else will output “object”.
console.log(typeof 6); // 'number'
console.log(typeof true); // 'boolean'
console.log(typeof 'nanjiu'); // 'string'
console.log(typeof []); // 'object' [] the data typeof the array is interpreted as object in typeof
console.log(typeof function(){}); // 'function'
console.log(typeof {}); // 'object'
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // the data typeof 'object' null is interpreted as object by typeof
Copy the code
For reference data types, typeof is not accurate, so you can use Instanceof to determine reference data types
instanceof
Instanceof can accurately determine the reference data type by detecting whether the constructor’s Prototype property is on the prototype chain of an instance object
For more information on prototyping, see my previous article: JavaScript prototypes and prototype chains you must Know
Grammar:
object instanceof constructor
console.log(6 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('nanjiu' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
Copy the code
Constructor ()
When a function is defined, the JS engine adds a Prototype attribute to the function, then adds a constructor attribute to the Prototype attribute and points it to the function.
When you performlet f = new F()
F is an instance object of F, and the constructor property on the prototype F is passed to F, sof.constructor===F
function F(){}
let f = new F()
f.constructor === F // true
Copy the code
new Number(1).constructor === Number //true
new Function().constructor === Function // true
true.constructor === Boolean //true
' '.constructor === String // true
new Date().constructor === Date // true
[].constructor === Array
Copy the code
⚠ ️ note:
- Null and undefined are invalid objects, so they do not have a constructor attribute
- The construct function is unstable, mainly because developers can override Prototype; the original construction reference is lost and constructor defaults to Object
function F(){}
F.prototype = {}
let f = new F()
f.constructor === F // false
console.log(f.constructor) //function Object(){.. }
Copy the code
Why is it Object?
Since prototype is reassigned to a {}, {} is the literal of new Object(), so new Object() passes the constructor from the Object prototype to {}, which is the Object itself.
Therefore, for standardized development purposes, when overriding an object prototype, it is generally necessary to re-assign constructor to ensure that the type of the object instance is not tampered with.
Object.prototype.toString.call()
ToString () is a prototype method for Object that, by default, returns the current Object’s [[Class]]. This is an internal property of the form [object Xxx], where Xxx is the type of the object.
For Object objects, toString() returns [Object Object]. For other objects, you need call/apply to return the correct type information.
Object.prototype.toString.call(' ');// [object String]
Object.prototype.toString.call(1);// [object Number]
Object.prototype.toString.call(true);// [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined);// [object Undefined]
Object.prototype.toString.call(null);// [object Null]
Object.prototype.toString.call(new Function());// [object Function]
Object.prototype.toString.call(new Date());// [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp());// [object RegExp]
Object.prototype.toString.call(new Error());// [object Error]
Object.prototype.toString.call(document);// [object HTMLDocument]
Object.prototype.toString.call(window);//[object global] window is a reference to global
Copy the code
3. Js data type conversion
There are three types of conversions in JavaScript:
- Convert to a Number(call the Number(),parseInt(),parseFloat() methods)
- Convert to a String(call the.toString() or String() method)
- Convert to Boolean(call the Boolean() method)
Null, undefined no. ToString method
Convert to numbers
- Number() : Converts any value to a Number and returns a value that is not a Number in the string to be converted
NaN
Number('1') // 1
Number(true) // 1
Number('123s') // NaN
Number({}) //NaN
Copy the code
- ParseInt (String,radix) : Parses a string and returns decimal integers of the specified radix,radix is integers between 2-36, representing the radix of the string being parsed.
parseInt('2') / / 2
parseInt('2'.10) / / 2
parseInt('2'.2) // NaN
parseInt('a123') NaN Returns NaN if the first character is not a number or symbol
parseInt('123a') / / 123
Copy the code
- ParseFloat (string) : Parses an argument and returns a floating point number
parseFloat('123a')
/ / 123
parseFloat('123a.01')
/ / 123
parseFloat('123.01')
/ / 123.01
parseFloat('123.01.1')
/ / 123.01
Copy the code
- Implicit conversion
let str = '123'
let res = str - 1 / / 122
str+1 / / '1231'
+str+1 / / 124
Copy the code
Convert to string
- .toString() ⚠️ note: null,undefined cannot be called
Number(123).toString()
/ / '123'
[].toString()
/ /"
true.toString()
//'true'
Copy the code
- String () can be turned
String(123)
/ / '123'
String(true)
//'true'
String([])
/ /"
String(null)
//'null'
String(undefined)
//'undefined'
String({})
//'[object Object]'
Copy the code
- Implicit conversion: When one of the two sides of + is a string and the other is another type, the other type is converted to a string and then concatenated to return a string
let a = 1
a+' ' / / '1'
Copy the code
Converts to a Boolean value
0, “(empty string), null, undefined, NaN will be converted to false, all other true
- Boolean()
Boolean(' ') //false
Boolean(0) //false
Boolean(1) //true
Boolean(null) //false
Boolean(undefined) //false
Boolean(NaN) //false
Boolean({}) //true
Boolean([]) //true
Copy the code
- Conditional statements
let a
if(a) {
/ /... // if a is undefined, it will be false, so the conditional statement will not be executed internally
}
Copy the code
- Implicit conversion!!
let str = '111'
console.log(!! str)// true
Copy the code
{} and [] return valueOf and toString?
- ValueOf: returns the original valueOf a specified object
object | The return value |
---|---|
Array | Returns the array object itself. |
Boolean | Boolean value. |
Date | The stored time is millisecond UTC from midnight on January 1, 1970. |
Function | The function itself. |
Number | A numeric value. |
Object | The object itself. This is the default. |
String | String value. |
Math and Error objects do not have valueOf methods. |
- ToString: Returns a string representing an object. By default,
toString()
Methods are used by eachObject
Object inheritance. If this method is not overridden in the custom object,toString()
Return “[objecttype], “one of themtype
Is the type of the object.
({}).valueOf() / / {}
({}).toString() //'[object Object]'
[].valueOf() / / []
[].toString() / /"
Copy the code
5. Let,const,var
- Variable promotion: let,const variables do not get promoted, whereas var does
- Block scope: let,const is block scope, that is, visible within the entire curly brace {}, var: there is only the concept of global scope and function scope, there is no concept of block scope.
- Duplicate declaration: Let variables declared by const are not allowed to duplicate declarations in the same scope as var variables
- Temporary dead zone: let,const variables cannot be used before the declaration, whereas var can
- Const declares a read-only constant and cannot be changed
6.JavaScript scope and scope chain
Scope:
Simply put, a scope is the area of a program where variables are defined, and it determines how much access the currently executing code has to the variables
Scope chain:
When the executable code accesses a variable internally, it looks for the variable in the current scope. If it does, it returns it immediately. If it does not, it looks for the variable in the parent scope. Go all the way to the global scope. We refer to this nesting mechanism of scopes as scope chains
For details, see my previous article: JavaScript depth scopes and closures
7. How to correctly judge the direction of this?
There are four binding rules for this: default binding, implicit binding, explicit binding, and new binding.
- Whether the function is called in new (new binding), and if so, this is bound to the newly created object in new.
- Whether the function is called by call,apply, or by using bind, if so, this binds to the specified object.
- Whether the function is called in a context object (implicitly bound), and if so, this binds to that context object. Usually obj. Foo ()
- If none of the above, use the default binding. If in strict mode, it is bound to undefined, otherwise to a global object.
- If null or undefined is passed to call, apply, or bind as a binding object for this, these values will be ignored during the call and the default binding rules will apply.
- The arrow function does not have its own this; its this inherits from the this of the previous code block.
See my previous article for details: This refers to call,apply, and bind
8.for… of,for.. What’s the difference between in,forEach,map?
for… Of (cannot traverse objects)
Create an iteration loop on an iterable (with an Iterator interface) (Array, Map, Set, String, arguments), call a custom iteration hook, and execute a statement for the value of each different property, not iterating through the object
let arr=["Front end"."South nine"."ssss"];
for (let item of arr){
console.log(item)
}
// Front-end NANjiu SSSS
// Iterate over the object
let person={name:"South nine".age:18.city:"Shanghai"}
for (let item of person){
console.log(item)
}
// We found that this is not possible. We can use it with object.keys
for(let item of Object.keys(person)){
console.log(person[item])
}
// Nanjiu 18 Shanghai
Copy the code
for… in
for… In loop: Iterates over an object’s own and inherited enumerable properties without directly fetching the property value. You can break the loop.
let person={name:"South nine".age:18.city:"Shanghai"}
let text=""
for (let i in person){
text+=person[i]
}
// Output: Nanjiu 18 Shanghai
// Second try some arrays
let arry=[1.2.3.4.5]
for (let i in arry){
console.log(arry[i])
}
//1, 2, 3, 4, 5
Copy the code
forEach
ForEach: the array can only be traversed without interruption, with no return value (or assumed to be undefined).
let arr=[1.2.3];
const res = arr.forEach(item= >{
console.log(item*3)})/ / 3 6 9
console.log(res) //undefined
console.log(arr) / / [1, 2, 3]
Copy the code
map
Map: The array can only be traversed without interruption, and the return value is the modified array.
let arr=[1.2.3];
const res = arr.map(item= >{
return res+1
})
console.log(res) / / / 2 and 4
console.log(arr) / / [1, 2, 3]
Copy the code
conclusion
- ForEach traverses list values without using break statements or return statements
- For in iterates through an object’s key or array index. It is not recommended to loop through an array
- Iterating over list values allows iterating over Arrays, Strings, Maps, Sets, and other iterable data structures. The for of loop was introduced in ES6 to replace for in and forEach() and to support the new iteration protocol.
- For in loops for key, for of loops for value;
- For of is a new feature introduced in ES6. [Fixed] ES5’s for in bug.
- For of cannot loop through ordinary objects, and must be used with object.keys ().
9. What is your understanding of prototype chain?
Every function (class) comes with a prototype property. The value of the property is an object that stores the properties and methods of the current class for instance use.
The browser default heap for the stereotype has a constructor property: stores the current class itself (⚠️ note: the constructor property is not available in the default heap, so you need to add it manually).
Each Object has a __proto__ attribute that points to the prototype of the class to which the current instance belongs.
When you try to get a property of an object, if the object doesn’t have the property itself, it will look in its implicit __proto__ (that is, the display prototype of its constructor). “(Prototype chain)”
For more information, see my previous article: JavaScript prototypes and prototype chains you must Know
10. Name three event models?
The event model
DOM0 level model: This model does not propagate, so there is no concept of event flow, but some browsers now support bubbling. It can define listeners directly in the web page, or it can specify listeners through JS properties. This approach is compatible with all browsers.
IE event model: In this event model, an event has two processes, the event processing phase and the event bubbling phase. The event processing phase first executes the listening event for the target element binding. Then there is the event bubbling phase, bubbling refers to the event bubbling from the target element to the document, checking whether the passing node is bound to the event listener function, and executing it if so. This model uses attachEvent to add listeners. Multiple listeners can be added and executed in sequence.
Dom2-level event model: In this event model, an event has three processes, the first of which is the event capture phase. Capture means that the event is propagated from the document all the way down to the target element, checking in turn to see if the passing node is bound to an event listener and executing it if it is. The latter two phases are the same as the two phases of the IE event model. In this event model, the event-bound function is addEventListener, where the third parameter specifies whether the event is executed during the capture phase.
Event delegation
Event delegation refers to delegating the events of one element to another element. Will, in general, the elements of one or a set of events entrusted to its parent layer or outer element, real binding event is outer element, when the incident response to need binding elements, through the event bubbling mechanism bind the event to trigger its outer elements, and then in the outer elements to perform the function.
Event Propagation (three stages)
- Capture phase – Events start at the window and work down to each element until the target element event or event.target is reached.
- Target phase – The event has reached the target element.
- Bubble phase – Events bubble up from the target element and then up to each element until they reach the Window.
Event capture
When an event occurs on a DOM element, it does not happen exactly on that element. In the capture phase, the event starts at the window and goes all the way to the element that triggered the event. Window – > document — — — — — — — — > > HTML body — — — – > target element
The event bubbling
Event bubbling is the opposite of event capture,Current element ---->body ----> HTML ---->document ---->window
. When an event occurs on a DOM element, it does not happen exactly on that element. In the bubble phase, the event bubbles, or the event occurs in its parent, grandparent, grandparent, until it reaches the window.
How do I prevent events from bubbling up
The W3C method is e.topPropagation (), IE uses e.ancelbubble = true. Such as:
window.event?window.event.cancelBubble = true : e.stopPropagation();
Copy the code
Return False also prevents bubbling.
11. Lazy loading of JS
JavaScript blocks DOM parsing and therefore DOM loading. So sometimes we want to delay JS loading to speed up the page loading.
- Put JS at the bottom of the page
- The defer property of the script tag: the script is downloaded immediately but deferred until the entire page has loaded. This property has no effect on inline scripts (that is, scripts without the “SRC” attribute).
- Async is executed after the external JS is loaded, when the browser is idle, and before the Load event is triggered. Scripts marked Async are not guaranteed to be executed in the order specified. This property has no effect on inline scripts (i.e. scripts without the “SRC” property).
- Dynamically create script tags, listen for dom loading before importing js files
12. What is modular development?
Modularized development can improve code reuse rate and facilitate code management. Usually a file is a module with its own scope, exposing only specific variables and functions.
Several modular schemes
-
The first is the CommonJS scheme, which imports modules via require and defines the module’s output interface via module.exports.
-
The second is THE AMD scheme, which adopts the asynchronous loading mode to load the module. The loading of the module does not affect the execution of the following statements. All statements that depend on the module are defined in a callback function, and the callback function is executed after the loading is complete. Require.js implements the AMD specification.
-
The third is CMD scheme, this scheme and AMD scheme are to solve the problem of asynchronous module loading, sea. Js implementation of CMD specification. It differs from require.js in how dependencies are handled in module definition and when dependent modules are executed.
-
The fourth solution is proposed in ES6, which uses the form of import and export to import and export modules.
CommonJS
Node.js is a major practitioner of the commonJS specification. This module loading solution is a server-side solution that introduces modules in a synchronous manner. Since files on the server side are stored on local disk, it is very fast to read, so it is no problem to load modules in a synchronous manner. However, on the browser side, asynchronous loading is more appropriate because the module is loaded using a network request.
// Define the module a.js
var title = 'front end';
function say(name, age) {
console.log(I was `${name}This year,${age}Welcome to pay attention to me ~ ');
}
module.exports = { // Write functions and variables that need to be exposed here
say: say,
title: title
}
// When referencing a custom module, the argument contains the path and can omit.js
var a = require('./a');
a.say('the south nine'.18); // I am Nan Jiu, 18 years old, welcome to follow me ~
Copy the code
AMD and require. Js
The AMD specification uses asynchronous loading of modules, which does not affect the execution of subsequent statements. All statements that depend on this module are defined in a callback function that will not run until the load is complete. Here is an introduction to implement the modularization of the AMD specification with require.js: specify the reference path with require.config(), define the module with define(), and load the module with require().
CMD and sea. Js
CMD is another JS modularization solution, which is similar to AMD, except that AMD advocates relying on front-loading and up-front execution, while CMD advocates relying on nearby and delayed execution. This specification was actually created during the promotion of Sea-js.
ES6 Module
ES6, on the level of language standards, implements module functions, and implements them quite simply, aiming to become a common module solution for browsers and servers. Its module functions are mainly composed of two commands: export and import. The export command is used to specify the external interface of a module, and the import command is used to input functions provided by other modules.
// Define the module a.js
var title = 'front end';
function say(name, age) {
console.log(I was `${name}This year,${age}Welcome to pay attention to me ~ ');
}
export { // Write functions and variables that need to be exposed here
say,
title
}
// When referencing a custom module, the argument contains the path and can omit.js
import {say,title} from "./a"
say('the south nine'.18); // I am Nan Jiu, 18 years old, welcome to follow me ~
Copy the code
CommonJS/ES6 Module differences
The CommonJS module prints a copy of the value, the ES6 module prints a reference to the value.
- The CommonJS module outputs a copy of the value, meaning that once a value is output, changes within the module do not affect that value.
- ES6 modules operate differently from CommonJS. The JS engine encountered a module load command while statically analyzing the script
import
, a read-only reference is generated. When the script is actually executed, it will be evaluated in the loaded module based on the read-only reference. In other words, ES6import
It’s kind of like a symbolic link on Unix, where the original value changes,import
The loaded value will also change. Therefore, ES6 modules are referenced dynamically and do not cache values. Variables in modules are bound to the module in which they are located.
The CommonJS module is run time loaded, and the ES6 module is compile time output interface.
- Runtime loading: CommonJS modules are objects; That is, the entire module is loaded on input, an object is generated, and methods are read from that object. This loading is called “runtime loading.”
- Load at compile time: ES6 modules are not objects, but pass
export
The command explicitly specifies the code to output,import
Is in the form of a static command. In theimport
You can specify that an output value is loaded instead of the entire module, which is called “compile-time loading.”
CommonJS loads an object (i.emodule.exports
Property), which is generated only after the script has run. An ES6 module is not an object, and its external interface is a static definition that is generated during the code static parsing phase.
Reading front-end modular Understanding is recommended
13. Talk about how JS works
Recommended reading exploring JavaScript execution mechanisms
14. How do I compare two objects in JavaScript?
For two non-basic types of data, we use either == or === to indicate whether their references are equal, not whether the actual references point to values that are equal.
For example, arrays are cast to strings by default, and all elements are concatenated with commas
let a = [1.2.3]
let b = [1.2.3]
let c = "1, 2, 3"
a == b // false
a == c // true
b == c // true
Copy the code
A recursive comparison is usually used to compare two objects
15. Tell me your understanding of closures, how they work and how they are used.
A combination of a function that is bound (or surrounded by) references to its surrounding lexical context is a closure.
Closure principle
Function execution is divided into two phases (precompilation phase and execution phase).
- During the precompilation phase, if an internal function is found to use variables from an external function, a “closure” object is created in memory and the value of the strain is saved. If the “closure” already exists, the attribute value is added.
- After execution, the function execution context is destroyed, as is the function’s reference to the closure object, but the inner function still holds the reference to the closure, so the inner function can continue to use the variables in the outer function
Take advantage of the function scope chain, inside a function definition of the function will include external function of the activities of the object to add to its scope chain, function and its implementation scope chain destruction, but because of the internal function scope chain is still in reference to the active object, so the activity object is not destroyed, it was not until after the internal function was burned down be destroyed.
advantages
- A variable in the scope of an external function can be accessed from an inner function, and the accessed variable is permanently stored in memory for later use
- Avoid variables contaminating the whole world
- Store variables in separate scopes as private members
disadvantages
- This has a negative impact on memory consumption. Because internal functions hold references to external variables, they cannot be garbage collected and increase memory usage, so improper use can lead to memory leaks
- It has a negative impact on processing speed. The hierarchy of closures determines the length of the scope chain through which referenced external variables are searched
- You may have captured unexpected values.
Application scenarios
- Module encapsulation, prevent variable pollution global
var Person = (function(){
var name = 'the south nine'
function Person() {
console.log('work for qtt')
}
Person.prototype.work = function() {}
return Person
})()
Copy the code
- Create a closure in the body of the loop to hold variables
for(var i=0; i<5; i++){ (function(j){
setTimeOut(() = > {
console.log(j)
},1000)
})(i)
}
Copy the code
Recommended reading: JavaScript deep scopes and closures
16.Object.is() and the comparison operator= =
,= = =
The difference between?
= =
Type conversion is performed before comparison= = =
The comparison does not cast; false is returned if the type is differentObject.is()
in= = =
On the basis of special treatmentNaN
.0
.+ 0
Guarantees that -0 is not equal to +0, but NaN is equal to NaN
= =
The cast rules for the operator
- Equality comparison between a string and a number, after converting a string to a number.
- Equality comparison between other types and Boolean types by converting Boolean values to numbers before applying other rules.
- An equality comparison between null and undefined. The result is true. Comparisons with other values return false values.
- An equality comparison between objects and non-objects that is performed after the object calls the ToPrimitive abstract operation.
- Equality comparison returns false if an operation has a NaN value (NaN itself is not equal to NaN).
- If both operation values are objects, compare them to see if they refer to the same object. The equality operator returns true if both operands refer to the same object, false otherwise.
'1'= =1 // true
'1'= = =1 // false
NaN= =NaN //false
+0= = -0 //true
+0= = = -0 // true
Object.is(+0, -0) //false
Object.is(NaN.NaN) //true
Copy the code
17. What is the difference between call and apply?
Call and Apply actually do the same thing, except that they pass arguments in a different way. Bind passes arguments in the same way as call, but it doesn’t execute immediately. Instead, it returns the function that this points to.
This refers to call,apply, and bind
18. Tell me what you know about front-end local storage.
Recommended reading: This time take you through front-end local storage
19. Talk about common JavaScript array methods
Add an element to an array:
- Push: Adds data to the end of an array and changes the array
- Unshift: Adding the return value to the beginning of the array is the new length of the array after adding data
- Splice: Inserts into the specified index of the array return a collection of deleted elements, altering the array
Delete an element from an array:
- Pop () : Removes an element from the tail and returns the deleted element, changing the array
- Shift () : Removing an element from the header returns the deleted element, changing the array
- Splice: Deleting howmany elements at index returns a collection of deleted elements, altering the array
Array sort method:
- Reverse () : changes the original array
- Sort () : Changes the array by the specified order
Array iteration method
Parameters: The function that runs on each item, and the scope object (optional) that runs the function
every()
Run the given function on each item in the array and return true if the function returns true for each item
var arr = [10.30.25.64.18.3.9]
var result = arr.every((item,index,arr) = >{
return item>3
})
console.log(result) //false
Copy the code
Some () runs the given function on each item in the array, returning true if one of the items returns true, and false only if all of the items return false
var arr2 = [10.20.32.45.36.94.75]
var result2 = arr2.some((item,index,arr) = >{
return item<10
})
console.log(result2) //false
Copy the code
filter()
For each run of the given function in the array, an array of items that satisfy that function is returned
// filter returns a new array of items that meet the requirements
var arr3 = [3.6.7.12.20.64.35]
var result3 = arr3.filter((item,index,arr) = >{
return item > 3
})
console.log(result3) / /,7,12,20,64,35 [6]
Copy the code
map()
Run the given function on each element of the array, returning the array as a result of each function call
// map returns an array of results from each function call
var arr4 = [1.2.3.4.5.6]
var result4 = arr4.map((item,index,arr) = >{
return `<span>${item}</span>`
})
console.log(result4)
/*[ '1', '2', '3', '4', '5', '6' ]*/
Copy the code
forEach()
Runs the given function on each element in an array, with no return value, often to traverse the elements
// forEach
var arr5 = [10.20.30]
var result5 = arr5.forEach((item,index,arr) = >{
console.log(item)
})
console.log(result5)
/* 10 20 30 undefined This method returns no value */
Copy the code
reduce()
The reduce() method performs a Reducer function (in ascending order) that you provide on each element in the array, summarizing its results into a single return value
const array = [1.2.3.4]
const reducer = (accumulator, currentValue) = > accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
Copy the code
20. Why does JavaScript promote variables, and what problems does it cause?
Variable promotion is when a variable is accessed or a function is called before it is declared without an error.
why
The JavaScript engine has a process of parsing (precompiling) code before it executes, creating execution scripts, and initializing objects that the code needs to use when it executes.
When access to a variable to the current execution context to look up the scope chain, and the first end of the scope chain point to is the variable object of the current execution context, the variable object is an attribute of the execution context, which contains the function parameter, all function and variable declarations, the object is created when the code parsing.
First of all, when JS gets a variable or a function, there will be two steps, namely parsing and execution.
-
In the parsing phase
JS checks the syntax and precompiles the function. Parsing will first create a global execution context, the first code to be executed in the variable, function declaration are taken out, variable first assigned to undefined, function first declared ready to use. Before a function is executed, a function execution context is also created, similar to the global execution context, except that the function execution context takes arguments to this, arguments, and the function.
- Global context: variable definition, function declaration
- Function context: variable definition, function declaration, this, arguments
-
In the execution phase, the code is executed in sequence.
So why do we do variable promotion? There are two main reasons:
- To improve performance
- Better fault tolerance
(1) Improve performance Before the JS code is executed, syntax checking and precompilation are performed, and this operation is performed only once. This is done to improve performance. Without this step, the variable (function) must be reparsed every time the code is executed. This is not necessary because the code does not change.
During parsing, precompiled code is also generated for the function. During precompilation, it counts which variables are declared, which functions are created, and compacts the function code to remove comments, unnecessary white space, and so on. The advantage of this is that you can allocate stack space directly to the function each time it executes (no need to parse again to get what variables are declared and what functions are created), and the code executes faster because of code compression.
(2) Better fault tolerance variable promotion can improve JS fault tolerance to a certain extent, see the following code:
a = 1
var a
console.log(a) / / 1
Copy the code
If there is no variable promotion, this code will report an error
Resulting problems
var tmp = new Date(a);function fn(){
console.log(tmp);
if(false) {var tmp = 'hello nanjiu';
}
}
fn(); // undefined
Copy the code
In this function, it was intended to print the TMP variable of the outer layer, but due to the problem of variable promotion, the TMP defined by the inner layer is moved to the top of the function, which overwrites the TMP variable of the outer layer, so the print result is undefined.
var tmp = 'hello nanjiu';
for (var i = 0; i < tmp.length; i++) {
console.log(tmp[i]);
}
console.log(i); / / 13
Copy the code
Since the traversal definition of I is promoted to a global variable that is not destroyed after the function ends, 13 is printed.
conclusion
- Improved declarations during parsing and precompilation can improve performance by allowing functions to pre-allocate stack space for variables at execution time
- Declaration promotion can also improve the fault tolerance of JS code, so that some non-standard code can be executed normally
- Functions are first-class citizens. When the function declaration conflicts with the variable declaration, the function takes precedence when the variable is promoted, and the variable declaration with the same name is ignored
Think the article is good, you can click a like ah ^_^ welcome to follow nanjiu ~