前端js题

505 阅读2分钟

js数组扁平化

  1. 使用数组的toString方法转化为字符串,再将字符串转回数组。需要注意数组转成字符串时数组的元素也被转成字符串类型了,所以数组元素不能为对象

     function flatten(arr) {
         return arr.toString().split(',').map(el => Number(el))
     }
    
  2. 使用递归,遇到数组元素为数组类型时逐个降维。这种方式不会对数组元素进行类型转换,数组元素可以为对象。

     function flatten(arr) {
         return arr.reduce((res, el) => {
             return res.concat(Array.isArray(el) ? flatten(el) : el)
         }, [])
     }
     
    

js数组去重

  1. 去重一个数组,使用Set

     function unique(arr) {
         var st = new Set(arr)
         return [...st]
     }
    
  2. 去重一个数组,使用对象属性

     function unique(arr) {
         const mp = {}
         return arr.filter(el => {
             return mp.hasOwnProperty(typeof el + el) ? false : mp[typeof el + el] = true
         })
     }
    
  3. 合并多个数组并去重

     function unique(...args) {
         var st = new Set()
         args.forEach(arr => {
             arr.forEach(el => {
                 if (!st.has(el)) st.add(el)
             })
         })
         
         return [...st]
     }
    
  4. 去重包含引用类型值的数组

     function unique(arr) {
         const mp = new Map()
         const _mp = new Map()
         arr.forEach((el, index) => {
             if (typeof el === 'object') {
                 let str = JSON.stringify(el)
                 if (_mp.get(str) === undefined) { _mp.set(str, index) }
             }else {
                 if (mp.get(el) === undefined) { mp.set(el, index) }
             }
         })
         let _arr = [...mp].concat([..._mp].map(el => [JSON.parse(el[0]), el[1]]))
                     .sort((a, b) => a[1]-b[1])
                     .map(el => el[0])
         return _arr
     }  
     
     
    

js对象的深拷贝和浅拷贝

浅拷贝

  1. 遍历对象的所有属性,进行赋值

     var _obj = {}
     Object.keys(obj).forEach(key => _obj[key] = obj[key])  
    
  2. 使用Object.assgin()

     var _obj = Object.assign({}, obj)  
    
  3. 使用收集展开运算符...

     var _obj = {...obj}
    

深拷贝

  1. 对对象进行序列化和反序列化,注意序列化会忽略值为undefined和function的属性

     var _obj = JSON.parse(JSON.stringify(obj))
    
  2. 对对象进行递归遍历

     function deepCopy(obj) {
         // 这样可以处理对象的属性为一个数组的情况
         var _obj = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {}
         for (let key in obj) {
             // 属性为对象或数组类型
             if (typeof obj[key] === 'object') _obj[key] = deepCopy(obj[key])
             // 属性为函数类型
             else if (typeof obj[key] === 'function') _obj[key] = eval(`(${obj[key].toString()})`)
             // 属性为简单基本类型
             else _obj[key] = obj[key]
         }
         return _obj
     }
    

    注意不支持拷贝对象的简写方法,原因出在对对象的简写方法调用toString(),返回的不是一个函数声明,使用eval解析执行时自然会报错

     var obj = {
         foo() {
             console.log('function foo')
         }
     }
     obj['foo'].toString()
     // 返回如下
    

     foo() {
       console.log('function foo')
     }