JS Basics: Knowledge Points

JavaScript basics

Closure

(1) What is a closure

Functions that can read variables inside other functions. The child level is searched up one level at a time, and the parent level cannot obtain the child level.

(2) Closure usage scenarios

Curry functions to prevent variables from being polluted.

(3) What problems can be caused by improper use of closures?

Improper use will create internal leaks; internal leaks: variables that cannot be accessed occupy memory;

Note) This rumor comes from: there is a bug in IE, the closure is used in IE, and the variables referenced in the closure cannot be recycled

(4) Summary

(1) Occupies more memory than ordinary functions.
(2) When the closure is not in use, it should be released in time.
(3) Assign null to the variable referencing the inner function object.

(5) JS garbage collection mechanism?

Unused objects/variables.
Unreachable objects (several objects form a ring, referencing each other)

(6) How to actively trigger the JS garbage collection mechanism

Set this value to null

(7) Garbage collection methods [2 types]

mark clearing, reference counting

Stabilization and throttling

(1) Principle

Anti-shake: Call [register phone number/email, form click] after inputting for a period of time
Throttling: Execute only once within the specified time [Search list, page scrolling, product window]

(2) Create a form demo

Example: Create a form submit button, click it multiple times, and hope that it can only be clicked once. Is there any solution?
(1) setTimeout usually uses this method (if you encounter more than one, encapsulate a method)
(2) [one size fits all] a button can no longer be requested when requesting other interfaces (define a loading, initially false. Change to true before requesting) Request complete or fail false)
(3) vue custom instruction

The difference between proto and prototype

Proto is an attribute that every instance has; prototype is only a constructor. The proto
in the instance and the prototype of the constructor refer to an object. *number has a prototype chain.

Note) proto can access properties on prototype.

(1) What is the difference between call, apply, and bind?

[All three can change the direction of this]
1. Grammar:

call(对象[,参数1,参数2,....])    //此地参数是指的是对象的参数,非方法的参数

 apply(对象, 参数数组)     // 参数数组形式: [参数1, 参数2, .....]

(2) Common points:

(1) All three can change the direction of this.
(2) The functions are basically the same, both of which implement inheritance/conversion of pointer objects. It is similar to the extend function of the facet object.

(3) Differences:

(1) The call can pass multiple parameters, and the second parameter and subsequent parameters can be any type of data.
(2) apply supports up to two parameters, and the second parameter must be an array.
(3) The bind parameter is the same as call, and the function will not be called. bind will not be executed immediately, but will return the function whose execution context has been changed.
(4) The first parameters of call and apply are both pointed to by this and executed directly. bind is to bind a function to an object.

What are the methods of copying?

(1) JSON.parse(JSON.stringify()) [The method of copying the prototype cannot be copied, and there will be problems with copying time/regularity]
(2) Recursion: [When it reaches 1000+, the recursion will explode]
(3) Object.assign: [ Only applicable to one-level objects], you can use Object.assign({}, obj)
(4) extend in JQ
(5) cloneDeep in lodash
(6) concat method: [connect two or more arrays, not Change the existing array to get a copy of the connected array]
(7) ES6 extension operator: you can use […xxx]
Note) Vue’s data is a shallow copy, data solves the independence and reusability, and there will be a call once A memory address does not affect each other.

What is the difference between shallow copy and deep copy? What scenario is it suitable for? How to write the specific function?

Shallow copy: Copy the address of the reference data type. If you change a value in memory, it will affect another object. [Shallow copy is the index of the copy]
Deep copy: copy reference type data, if one of the values ​​is changed, the other object will not be affected. [Deep copy is data]

Note) The new methods in es6 are all deep copies. When you use the value of an object and don't want to change the original object, you can use deep copy to create a new memory object.

What's wrong with JSON.parse(JSON.stringify()) deep copy?

Methods that cannot copy the prototype will also have problems with copy time/regularity.
Note) To put it simply, it can copy flat data such as array, string, number, and boolean, and express it directly in JSON.
How to solve the recursion into an infinite loop?
Judgment by boundary value.

Browser reflow and redraw

Reflow: When the page structure changes, reflow will be triggered

页面一开始渲染
浏览器窗口大小变化
元素位置发生变化
元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
内容发生变化(比如文本变化或图片被另一个不同尺寸的图片所替代)

Redraw: Do not change the page structure, only change the appearance and style of elements; such as background color, etc.

颜色修改
文本方向修改
阴影修改

Note) reflow will definitely trigger redrawing, reflow consumes more performance than redrawing;
optimization method: when modifying elements, try not to modify the original style, and increase it through class

What is the principle of the browser?

(1) browser input address
(2) DNS resolution
(3) TCP protocol
(4) http send request
(5) server processing returns processing result
(6) browser display

Why do browsers cross domains? 【Same Origin Policy】

When the front and back ends are separated, and the domain names of the front and back ends are different, cross-domain problems will occur. Because in the request we are generally get/post requests.
Note) Same-origin policy: If the port, protocol, and host number are the same, they are of the same origin.

How to solve cross domain? 【6 types】

(1) Add header when requesting: header('Access-Control-Allow-Origin:*')
(2) JSONP
(3) postMessage
(4) nginx forwarding
(5) websocket
(6) local web service/cdn

What is the difference between JSON and JSONP?

JSON: The returned string.
JSONP: Returned script code (including functions)

(1) Difference

JSON is the ideal data to obtain, and cannot be requested through cross-domain; so put json in a legal language and pass it as a JS file.
json is what you want; jsonp is a commonly used method to achieve the goal, and ultimately json.
json is the end; jsonp is the means. json will always be used, and jsonp will be used across domains.

The principle of JSONP?

Implement cross-domain requests through script tags. There is src in it, which is not affected by the same-origin policy and can be accessed anywhere.

es5 inheritance and es6 inheritance implementation method? and the difference?

(1) First of all, we must know JS inheritance [4 types]: prototype inheritance, real inheritance, constructor inheritance, and copy inheritance.
(2) es5 mainly through property or constructor.

[es5 inheritance is essentially to create the instance object of the subclass first, and then add the parent instance object to this]

(3) ES6 uses the class keyword, which contains constructors, and the classes implement inheritance through the extends keyword.

[Completely different from the es5 inheritance mechanism. In essence, first create the parent class instance object this (the super method must be called first), and then use the subclass constructor to modify this]

What is the difference between primitive types and reference types?

(1) Basic types [number, boolean, string, null, undefined, symbol]
are accessed by value and can operate on values.
(2) Reference type [object (array, function, etc.)]
Note) Simply speaking, the type is judged by typeof, and the value is object/function is the reference type.
The type returned by typeof: string, boolean, undefined, object, function, number

typeof null  // object
typeof object // function
typeof {
    
    } // object
typeof [] // object

What are the JS built-in objects?

Basic objects: object, boolean, symbol, function.
Error Objects: error,
Number and Date Objects: Date, bigInt, Number, Math.
String: Regular (RegExp), String

[For details, please refer to the link: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects]

How many methods are there for ajax request? What is the difference between get and post?

Request method [4]: ​​get, post, put, delete. There are also HEAD, TRACE, CONNECT, OPTIONS methods.
get: Use url or cookie to pass parameters, fast speed, size limit, unsafe; generally used for creation.
post: Put the data in the body, no size limit, slow speed, safe; generally used for deletion/modification.
Face-to-face understanding: essentially the same, the difference lies in the different browser restrictions

Note) Baidu search uses get request, for the convenience of users.

What is the difference between click and on in JQ?

There is no difference when using static resources. Only on can take effect when dynamic;

Macro tasks and micro tasks [Another question is: event rotation]

(1) Execution sequence: first synchronous and then asynchronous, first micro-tasks and then macro-tasks.
(2) In the task queue: Outer tasks -------- micro tasks --- macro tasks
(3) Macro tasks: tasks executed in the call stack at that time
[main code block, setTimeout, setInterval, setImmediate , requestAnimationFrame]
(4) Microtask: The current (in this event loop) macrotask execution is completed, and the task that needs to be executed before the next macrotask starts is the microtask [
promise.then, process.nextTick, MutationObserver, catch, finally]

Note) The events of the macro task are placed in the callback queue and maintained by the event trigger thread; the events of the micro task are placed in the micro task queue and maintained by the js engine thread.

What is the difference between setTimeout, promise, async?

async is implemented based on promises. promises are ES6. async is ES7.
1. setTimeout is a macro task, and the callback function is placed in the macro task queue and executed after the execution stack is cleared.
2. Promise is a microtask, and the callback function is placed in the microtask in the macrotask, and is executed after the synchronization code in the macrotask is executed.
3. async means that there is an asynchronous operation behind, and await is followed by an expression. When the async method is executed, the expression will be executed immediately when it encounters await, and then the code of the expression will be put into the i microtask, and the execution stack will be released to allow the synchronous code to execute first.

Note) This question mainly examines the difference between the three in the loop, event loop [2 types]: macro task, micro task.

When will promise be used? What are the methods? How to use respectively?

(1) understand

When there is no promise, it is used nested. Promise appears simply for the purpose: callback solves asynchronous problems.

(2) Promise method

(1) promise.then() If there is no error, execute the .then method in turn.
(2) promise.all() can execute multiple operations in parallel and process the returned data in one callback.
(3) promise.catch().then uses catch when something goes wrong, and uses its own error method if it has its own err.
(4) promise.finally() Regardless of the state, the finally method will be executed after executing then and catch.
(5) promise.race () wraps multiple promise instances into one.
(6) promise.resove() converts an existing object into a promise object.
(7) promise. reject()

(3) Application scenarios

(1) Promise is used when the image is loaded.
(2) all() realizes the merging of multiple requests together, summarizing the request results, and only needs to set a loading.
(3) race () sets the image request timeout.

Note) Write asynchronous code in a synchronous manner. There are only three states in a promise: in progress, success, and failure.
When using promise, if it is followed by a synchronous task, return directly; if it is followed by an asynchronous task, a new promise method needs to be returned.

(4) What to do when promise.all () fails?

1. If there are seven or eight interfaces to deal with [2 methods]: use promise.all or async/await.
2. When using promise.all(), if one of the tasks fails, the catch will occur. How to solve it? [2 methods]
(1) Change to serial
(2) When the promise captures an error, eat the exception and change it to resolve, and agree on a special format to indicate that the call is successful

The for loop uses var and let respectively?

for is a synchronous task; setTimeout is an asynchronous task
(1) when the asynchronous task is performed, the for loop has finished looping, so the obtained value i is the same variable i = 5 after the loop is completed; (2
) let has block-level scope, and every In the second loop, i in the block-level scope exists independently, and the bottom layer of the js engine remembers the value of i for each iteration, so the final print result is 0 1 2 3 4;

for(var i = 0;i < 5; i++) {
    
    
    setTimeout(() => {
    
    
        console.log(i)    
    })
}
// var ->输出5次 5
// let -> 0,1,2,3,

js error stack overflow? Is there any way to locate which piece of code?

Overflow is an infinite loop. If you accumulate too many variables and don’t release them, you will definitely overflow.
Positioning: You can only check the code to see if there is a recursive method; or store something in it; or the element is removed, but the bound event is not removed.

How does the front end render tens of thousands of pieces of data? [The main question may still be setTimeout]

1. document.createDocumentFragment( ) is used to create a virtual node, and the node object does not belong to the document tree.
2. When you need to add multiple doms, you can add the doms to the virtual node first, and finally add the virtual node to the page, which can reduce the number of dom operations.
3. JS is single-threaded, using the two functions setTimeout and setInterval is similar to multi-threading

Event delegation, event bubbling, event capture

Event delegation: Let the parent do what you don’t want to do (use the event bubbling principle to add the event to the parent)
Event bubbling: trigger from top to bottom (stop event bubbling: event.stopPropagation())
Event capture: get event nodes through document, trigger from top to bottom

Note) There are two streams in the DOM: event bubbling and event capture

cache

(1) cookie (same origin is 4KB; supports all browsers; generally used when logging in)
(2) localStorage (same origin 5MB; if not manually cleared, it will always be in the browser)
(3) sessionStorage (same origin 5MB ; browser window closes data loss)

Purpose [2]: High performance, high concurrency.

What exactly does the new operator do?

1. Create an empty object, and the this variable refers to the object, and also inherits the prototype of the function.
2. Properties and methods are added to the object referenced by this.
3. The newly created object is referenced by this, and finally implicitly returns this

What does this point to?

1)箭头函数中:指的上下文this,且不能改变。2)普通函数/定时器:指的 window。3)构造函数:指的是实例对象(new 会改变 this 指向)4)通过事件绑定的 this: 指的是绑定的这个 this5)对象中:该方法所性的对象6)在函数中:this 是隐式参数。7)函数外,浏览器中:this是全局对象。8)node.js 中:this 指的是 模块 import,导出 export9)传递到evel 中:直接掉用this 指的 当前对象;间接掉用 this 指的是全局对象。

What is the difference between window and document?

1. window is a form; document is a page.
2. document is a child object of window.
3. document.localtion can change the content of the current page; window.location can replace the current one with other documents.
4. window.location is an object, but document.localtion is not an object.

How does JS catch exceptions?

try{
    
    
// 运行代码
}catch {
    
    
// 错误运行
}

function declaration

Function declaration is greater than variable declaration
Function promotion rules Function literal == variable declaration
In code block: function declaration will be promoted to the top of the scope, but function declaration is greater than variable declaration

ES6

What are the new features of es6?

(1) let and const
(2) string template [ ${abc}]
(3) arrow function
(4) promise
(5) deconstruction
(6) import and export
(7) class definition and inheritance
(8) object extension, function extension
(9) ) proxy
(10) map, set deduplication, for of
(11) extension operator […obj]

What is the difference between an arrow function and a normal function?

Arrow function is a new feature of es6. It is an anonymous function. It cannot be created with new and has no prototype.

What is the difference between var, let, and const?

The declaration of var hangs on the window, and the variable name can be promoted.
let is a variable.
const is a constant and cannot be empty. Once it is declared, it must be assigned; if it declares a composite object, its properties can be modified.

Note) let and const will form a block scope, once declared can not be repeated

string expansion

1. Retrieve the string:

(1).includes(),语法格式为:A.includes(B,index),判断A是否包含B,index表示检索的位置,从第index位置开始检索
(2).startsWith(), 语法格式为:A.includes(B,index),判断A是否以B开头,index表示检索的位置,从第index位置开始检索
(3).endsWith(), 语法格式为:A.endsWith(B,index),判断A是否以B结尾,index表示对前index个字符进行检索,这三个语句的index都是可以省略的,省略则表示检索整个字符串。

2. Repeat string:

(1).语法格式为str.repeat(n);
(2).repeat()并不会改变原来的字符串,因此需要一个变量用来接收重复后的结果,

3. Remove white space

(1).trim(),语法格式为str.trim(),用于去除字符串首尾的空格
(2).trimStart(),语法格式为str.trimStart(),用于去除字符串开始处的空格
(3).trimEnd(),语法格式为str.trimEnd(),用于去除字符串结尾处的空格

What is the difference between TS and es6?

Two types of TS: internal, external; scope [3] global, local, class scope.
Two types of es6: import and export; scope [2] global and local.

Optimize & use

How to control the git version?

Withdraw commit operation: git reset --soft HEAD^
Revert version: git reset HEAD~
Revert specified version: git reset --hard id
modify commit Description: git reset --amend
git config --gobal --list

(1) Process

git stash (put the modified file in the cache)
git pull (pull the remote code)
git stash pop (release the file in the cache)
git add . (add the file to be submitted)
git commit -m '' ( Submitted text description)
git push orign branch number (committed to a branch)

(2) commonly used

git fetch origin (pull and update remote branch)
git config user.name 'xxx' (the name displayed when submitting)
git config user.email 'xxx' (the email address displayed when submitting)
git clone xxx (clone)
git checkout xxx ( Switch project branch)
git checkout -b branch (create a branch and stay on the current branch)
git branch (pull branch)
git branch -r (pull remote branch)
git branch -r (current local branch)
git log (view log)

Code optimization

(1) Use less global variables
(2) Use innerHTML instead of DOM operations to reduce the number of DOM operations and optimize javascript performance
(3) Use setTimeout to avoid page loss of response
(4) Cache the results of DOM node search
(5) Avoid using CSS Expression
(6) Avoid global queries
(7) Avoid using with (with will create its own scope, which will increase the length of the scope chain)
(8) Merge multiple variable declarations
(9) Avoid empty Src for pictures and iFrames. Empty Src will reload the current page, affecting speed and efficiency
(10) Try to avoid writing Style attributes in HTML tags

What are the commonly used status codes? What do they represent?

2xx: The interface is processed normally
200: The request is successful
204: The request is successful and there is no resource
3xx: The browser needs special processing
301: Permanent orientation, the url resource location has been replaced,
302: Temporary orientation, the url is temporarily changed to another location
303: Resource Update, you must use the GET method
304: resource found, but there is no eligible
307: almost the same as 302
4xx: the server cannot request
400: bad request, the server does not understand
401: http authentication is required
403: forbidden, the server forbids the request
404: the page is not available 5xx found
: server processing error
500: internal server error
501: not yet implemented
502: bad gateway
503: server unavailable (overloaded/down)
504: gateway timed out
505: http version not supported

JS new features

参考:【https://blog.csdn.net/weixin_46719229/article/details/122313154】

What does the + in front of a JS variable mean? 【Example: +value】

Can be understood as Number (value)

Optional chaining operator (?.)

Allows reading the value of properties located deep in a connection object chain without having to explicitly verify that each reference in the chain is valid

Reference link: https://blog.csdn.net/weixin_38551805/article/details/116199959

const dog = {
    
    
    prop: {
    
    
        name: '小七',
        ege: ''
    }
}
dog?.prop?.name // '小七'
dog?.prop?.ege // ''

Null coalescing operator (??)

Only when the left side is null and undefined, the number on the right will be returned , otherwise returns the left operand.

null ?? 20  // 20
undefined ?? 3 // 3
'' ?? 3 // ''
0 ?? 4 // 0

array

JS has several data classes [8 types]

string、number、null、boolean、object、undefined、symbol、bigInt

Note) Symbol is a new addition to es6. This type of object is never equal, and the same value is passed in when it is created to resolve attribute name conflicts as a mark.
bigint appeared in chrome 67.

What are NaNs?

Non-numeric, a special type in Number.

What is the reason for null to exist? How to deal with it?

The reason null exists is for an empty object, which doesn't exist.
When making judgments, put the null judgment at the top.

What is the difference between == and === in Js?

== values ​​are equal; === both values ​​and types are equal.

The method of judging whether it is an array [4]

(1)Array.isArray()

(2)constructor

(3)instanceof

(4) Object.prototype.toString.call (judgmental) === '[object Array]'

The return values ​​of some and every?

Returns true and false. some is one satisfaction, every is all satisfactions.

Commonly used: Shopping cart select all and select multiple.

change the original array

【push、pop、shift、unshift、splice、reverse、sort、forEach】

do not change the original array

【map、filter、reduce、join、slice、concat、some、every】

iterate over the array

【map、filter、reduce、every、some、forEach】

typeof ["men's pants", "women's pants"] Why is it an object and not an array?

The array itself is also an object. To determine whether it is an array, typeof cannot be used, and Array.isArrray() or arr instanceof Array should be used. The point of this question is to ask about basic data types.

What is the difference between map and forEach?

map does not change the original data, but forEach changes the original array.

Note) Create a new array with map; you don't need to make a new array, just use forEach when you need to change.

Can map, filter, forEach, some, every break out of the current loop?

map, filter, forEach can't, and break can't work either.
some can, return false
every can jump out of the current loop: return activityrules

JS rounding up, rounding down, rounding, m to the nth power?

[The point I want to ask is JS built-in objects]

1)向上取整:Math.ceil(5.123) // 6 2)向下取整:Math.floor(5.123) // 53)四舍五入:Math.round(5.432) // 54)绝对值:Math.abs(-1)  // 15)取最大值:Math.max(1,2,3)  // 36)取最小值:Math.min(1,2,3) // 17)随机数:Math.random()8)m的n 次方:Math.pow(2,4) // 16 (2的4次方)
(9)保留小数:parseFloat(3.44)  // 3.44
(10)保留整数:parseInt(3.44)  // 3

Commonly used methods for arrays

1)字符串转数组:split2)数组转字符串:join3)substring: 提取字符串,日期第几位到第几位4)indexOf: 第一次出现的索引位置5)lastIndexOf: 最后一次出现的索引位置6)push: 在数组后面添加一个值,返回新的长度。7)pop:  删除最后一个值,返回删除的值。8)shift:  删除第一个值,返回删除的值。9)unshift: 在数组前面添加一个值,返回新的长度。10)reverse: 从大到小排序。11)sort: 从小到大排序。22)splice :从数组中获取添加/删除对象,返回被删除的元素。23)slice :选回返定的元素。24)concat : 连接两个或多个数组,返回新的数组,不改变原数组

Object array merge [concat, traversal +, apply]

1)concat 方法【不改改原数组】
    var a=[1,2,3],b=[4,5,6];
    var c=a.concat(b);
    console.log(c) // 1,2,3,4,5,62)map遍历
    var arr1=[1,2,3],arr2=[4,5,6];
    arr2.map(item =>{
    
    
        arr1.push(item)
    })
    console.log(arr1) // 1,2,3,4,5,63)apply
    var a=[1,2,3],b=[4,5,6];
    a.push.apply(a,b)
    console.log(a)  // 1,2,3,4,5,6

Object merge【$extend, traversal+for in, Object.assign】

1)$extend
    var a= {
    
    'a': 1}, b= {
    
    'b': 1};
    $.extend(a,b)
    console.log(a)2)遍历 + for in
    let a = {
    
    a: 1},b = {
    
    b: 2, c: 3, d: 4}
    for(let i in b){
    
    
        // hasOwnProperty是判断自有属性
        // for in 循环遍历对象属性时,原型链上所有属性都将被访问,会避免原型对象扩展带来的干扰
     	if(b.hasOwnProperty(i) === true) {
    
     
          a[i] = b[i]
        }
    }
    console.log(a) // { a: 1, b: 2, c: 3, d: 4 }3)Object.assign 
    let a = {
    
    a: 1},b = {
    
    b: 2},c = {
    
    c: 3},d = {
    
    d: 4};
    let arr = Object.assign(a,b,c,d)
    console.log(a) // { a: 1, b: 2, c: 3, d: 4 }
    console.log(arr) // { a: 1, b: 2, c: 3, d: 4 }

Count the number of occurrences of an array element

let demo = ['aa','bb','cc','aa','1','cc','cc','bb']
let obj = {
    
    }
demo.map(item =>{
    
    
    if(obj[item]){
    
    
        obj[item]=obj[item]+1;
    } else {
    
    
        obj[item] = 1
    }
})
console.log(obj) // {1: 1, aa: 2, bb: 2, cc: 3}

What is the difference between for of and for in? How can for of make object traversal?

(1) Difference: the code is as follows

The for in traversal obtains the key of the object, that is, the index value.
The for of traversal obtains the value of the object, that is, the value of the object.

var arr = ['red', 'green', 'blue']1for in 遍历获取的是对象的 key,就是索引值
    for(let item in arr) {
    
    
      console.log('结果', item)
    }
    > "结果" "0"
    > "结果" "1"
    > "结果" "2"2for of 遍历获取的是对象的 关键字,就是值        
    for(let item of arr) {
    
    
      console.log('结果', item)
    }
    > "结果" "red"
    > "结果" "green"
    > "结果" "blue"3for of 怎么能使对象遍历

What are the methods for deduplication of arrays? [12 types] What is the difference between array deduplication and object deduplication?

(1) filter
(2) reduce + includes
(3) includes (judging whether there is this value)
(4) indexOf (judging by indexOf === -1)
(5) for nesting, inside splice deduplication
(6) sort Sorting, comparing with adjacent elements
(7) […new Set(arr)]
(8) set deduplication
(9) recursive deduplication

方法8:Array.from(new Set(arr))

方法34:includes、indexOf
function unique(arr) {
    
    
    // 先判断是不是数组
    if (!Array.isArray(arr)) {
    
    
        console.log('type error!')
        return
    }
    var array = [];
    for (var i = 0; i < arr.length; i++) {
    
    
        // indexOf 方法
        if (array.indexOf(arr[i]) === -1) {
    
    
            array.push(arr[i])
         }
        // includes 方法
        if(!array.includes(arr[i])) {
    
    
          array.push(arr[i])
        }
    }
    return array;
}
方法5for 嵌套,里面splice 去重
function unique(arr){
    
                
        for(var i=0; i<arr.length; i++){
    
    
            for(var j=i+1; j<arr.length; j++){
    
    
                if(arr[i]==arr[j]){
    
             //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j,1);
                    j--;
                }
            }
        }
return arr;
}

//数据
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{
    
    },{
    
    }];
console.log(unique(arr))
//结果 [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]  //NaN、{}没有去重

Guess you like

Origin blog.csdn.net/u013592575/article/details/124736358