JavaScript基础面试题总结03

1. 多维数组降维的几种方法?

1、数组字符串化

  let arr = [
    [222, 333, 444],
    [55, 66, 77]
  ]
  arr += ''
  arr = arr.split(',')
  console.log(arr) // ['222', '333', '444', '55', '66', '77']

2、递归

  function reduceDimension(arr) {
    let ret = []
    let toArr = function (arr) {
      arr.forEach(function (item) {
        item instanceof Array ? toArr(item) : ret.push(item)
      })
    }
    toArr(arr)
    return ret
  }

3、Array.prototype.flat()

  var arr1 = [1, 2, [3, 4]]
  arr1.flat() // [1, 2, 3, 4]
  var arr2 = [1, 2, [3, 4, [5, 6]]]
  arr2.flat() // [1, 2, 3, 4, [5, 6]]
  var arr3 = [1, 2, [3, 4, [5, 6]]]
  arr3.flat(2) // [1, 2, 3, 4, 5, 6]
  // 使用 Infinity 作为深度,展开任意深度的嵌套数组
  arr3.flat(Infinity) // [1, 2, 3, 4, 5, 6]

4、使用 stack 无限反嵌套多层嵌套数组

  var arr1 = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]] 
  function flatten(input) {
    const stack = [...input]
    const res = []
    while (stack.length) {
      // 使用 pop 从 stack 中取出并移除值
      const next = stack.pop()
      if (Array.isArray(next)) {
        // 使用 push 送回内层数组中的元素,不会改动原始输入 original input
        stack.push(...next)
      } else {
        res.push(next)
      }
    }
    // 使用 reverse 恢复原数组的顺序
    return res.reverse()
  }
  flatten(arr1) // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

5、使用 reduce、concat 和递归无限反嵌套多层嵌套的数组

  var arr1 = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]]
​
  function flattenDeep(arr1) {
    return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), [])
  }
  flattenDeep(arr1) // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]

2. 怎么判断两个对象相等?

ES6 中有一个方法判断两个对象是否相等,这个方法判断是两个对象引用地址是否一致

  let obj1 = {
    a: 1
  }
  let obj2 = {
    a: 1
  }
  console.log(Object.is(obj1, obj2)) // false
  let obj3 = obj1
  console.log(Object.is(obj1, obj3)) // true
  console.log(Object.is(obj2, obj3)) // false

当需求是比较两个对象内容是否一致时就没用了。

想要比较两个对象内容是否一致,思路是要遍历对象的所有键名和键值是否都一致:

1、判断两个对象是否指向同一内存

2、使用 Object.getOwnPropertyNames 获取对象所有键名数组

3、判断两个对象的键名数组是否相等

4、遍历键名,判断键值是否都相等

  let obj1 = {
    a: 1,
    b: {
      c: 2
    }
  }
  let obj2 = {
    b: {
      c: 3
    },
    a: 1
  }
​
  function isObjectValueEqual(a, b) {
    // 判断两个对象是否指向同一内存,指向同一内存返回 true
    if (a === b) return true
    // 获取两个对象键值数组
    let aProps = Object.getOwnPropertyNames(a)
    let bProps = Object.getOwnPropertyNames(b)
    // 判断两个对象键值数组长度是否一致,不一致返回 false
    if (aProps.length !== bProps.length) return false
    // 遍历对象的键值
    for (let prop in a) {
      // 判断 a 的键值,在 b 中是否存在,不存在,返回 false
      if (b.hasOwnProperty(prop)) {
        // 判断 a 的键值是否为对象,是则递归,不是对象直接判断键值是否相等,不相等返回 false
        if (typeof a[prop] === 'object') {
          if (!isObjectValueEqual(a[prop], b[prop])) return false
        } else if (a[prop] !== b[prop]) {
          return false
        }
      } else {
        return false
      }
    }
    return true
  }
  console.log(isObjectValueEqual(obj1, obj2)) // false

3. 什么是类数组(伪数组),如何将其转化为真实的数组?

伪数组

1、具有 length 属性

2、按索引方式存储数据

3、不具有数组的 push.pop 等方法伪数组(类数组):无法直接调用数组方法或期望 length 属性有什么特殊的行为,不具有数组的 push.pop 等方法,但仍可以对真正数据遍历方法来遍历它们。典型的是函数 document.childnodes 之类的,它们返回的 nodeList 对象都属于伪数组

伪数组转化为真实数组的方法

1、使用 Array.from()--ES6

2、[].slice.call(eleArr) 或则 Array.prototype.slice.call(eleArr)

  let eleArr = document.querySelectorAll('li')
  Array.from(eleArr).forEach(function (item) {
    alert(item)
  })
​
  let eleArr = document.querySelectorAll('li')
  let arr = []
  arr.slice.call(eleArr).forEach(function (item) {
    alert(item)
  })

4. 如何遍历对象的属性?

1、遍历自身可枚举的属性 (可枚举,非继承属性) Object.keys() 方法

该方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中的属性名的排列顺序和使用 for..in 遍历该对象时返回的顺序一致(两者的区别是 for ..in 还会枚举其原型链上的属性 )

  /** Array 对象 **/
  var arr = ['a', 'b', 'c']
  console.log(Object.keys(arr)) // ['0','1','2']
  /** Object 对象 **/
  var obj = {
    foo: 'bar',
    bar: 42
  }
  console.log(Object.keys(obj)) // ["foo","bar"]
  /** 类数组对象 随机 key 排序 **/
  var anObj = {
    100: 'a',
    2: 'b',
    7: 'c'
  }
  console.log(Object.keys(anObj)) // ['2','7','100']
  /** getFoo 是一个不可枚举的属性 **/
  var my_obj = Object.create({}, {
    getFoo: {
      value: function () {
        return this.foo
      }
    }
  })
  my_obj.foo = 1
  console.log(Object.keys(my_obj)) // ['foo']

2、遍历自身的所有属性(可枚举,不可枚举,非继承属性) Object.getOwnPropertyNames() 方法

该方法返回一个由指定对象的所有自身属性组成的数组(包括不可枚举属性但不包括 Symbol 值作为名称的属性)

  // 数组
  var arr = ["a", "b", "c"]
  console.log(Object.getOwnPropertyNames(arr).sort()) // ['0', '1', '2', 'length']
  // 类数组对象
  var obj = {
    0: "a",
    1: "b",
    2: "c"
  }
  console.log(Object.getOwnPropertyNames(obj).sort()) // ['0', '1', '2']
  // 使用 Array.forEach 输出属性名和属性值
  Object.getOwnPropertyNames(obj).forEach(function (val, idx, array) {
    console.log(val + " -> " + obj[val])
  })
  // 输出
  // 0 -> a
  // 1 -> b
  // 2 -> c
  // 不可枚举属性
  var my_obj = Object.create({}, {
    getFoo: {
      value: function () {
        return this.foo;
      },
      enumerable: false
    }
  })
  my_obj.foo = 1
  console.log(Object.getOwnPropertyNames(my_obj).sort()) // ["foo", "getFoo"]

3、遍历可枚举的自身属性和继承属性 (可枚举,可继承的属性) for in 遍历对象的属性

注:hasOwnProperty()方法判断对象是有某个属性(本身的属性,不是继承的属性)

  var obj = {
    name: '张三',
    age: '24',
    getAge: function () {
      console.log(this.age)
    }
  }
  var arry = {}
  for (var i in obj) {
    if (obj.hasOwnProperty(i) && obj[i].typeOf != 'function') {
      arry[i] = obj[i]
    }
  }
  console.log(arry) // {name: '张三', age: '24', getAge: ƒ}

4、遍历所有的自身属性和继承属性

  (function () {
    var getAllPropertyNames = function (obj) {
      var props = []
      do {
        props = props.concat(Object.getOwnPropertyNames(obj))
      } while (obj = Object.getPrototypeOf(obj))
      return props;
    }
    var propertys = getAllPropertyNames(window)
    alert(propertys.length) // 1068
    alert(propertys.join("\n")) //Object 等
  })()

5. 如何实现数组的随机排序?

方法一:

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
​
    function randSort1(arr) {
      for (var i = 0, len = arr.length; i < len; i++) {
        var rand = parseInt(Math.random() * len)
        var temp = arr[rand]
        arr[rand] = arr[i]
        arr[i] = temp
      }
      return arr
    }
    console.log(randSort1(arr))

方法二:

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
​
    function randSort2(arr) {
      var mixedArray = []
      while (arr.length > 0) {
        var randomIndex = parseInt(Math.random() * arr.length)
        mixedArray.push(arr[randomIndex])
        arr.splice(randomIndex, 1)
      }
      return mixedArray
    }
    console.log(randSort2(arr))

方法三:

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    arr.sort(function () {
      return Math.random() - 0.5
    })
    console.log(arr)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

端端1023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值