微信扫一扫看面试题

关注面试题库

无论如何,你都必须得知道的js知识(续)

outside_default.png

前言

分享一款前端面试题库 地址:   前端面试题库

碎碎念

  此分类用于记载我认为需要整理的js知识以及我不知道的js知识。因为是利用零碎时间去整理一些笔记,所以这篇文章后续会持续更新,有兴趣的小伙伴可以先收藏吃灰,哈哈哈。

24. reduce函数剖析(补充)

7. 利用reduce函数将二维数组转换为一维数组

let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre, cur) => pre.concat(cur), [])
console.log(newArr)  // [0, 1, 2, 3, 4, 5]

8. 利用reduce函数将多维数组转换为一维数组

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
`相较于二维数组的转换,多了一层递归处理`
let newArr = arr => arr.reduce((pre,cur) => pre.concat(Array.isArray(cur) ? newArr(cur) : cur), [])
newArr(arr)  // [0, 1, 2, 3, 4, 5, 6, 7]
复制代码

25. 关于js中的内存机制

  js栈内存和堆内存详解—图解基本数据类型和引用数据类型的区别。堆栈这种数据结构,具有先进后出,后进先出的特点,先明细几个概念:

  • 栈内存:计算机为浏览器执行js代码,在内部开辟的空间,也被称为执行环境栈。里面存放的是基本数据类型以及对象类型数据的引用地址,地址指向了堆内存里的对象内容。由于栈内存中存放的基础数据类型的大小是固定的,所以栈内存的内存都是操作系统自动分配和释放回收的。

  • 堆内存: 堆内存里存放的是除函数的引用类型的值,如数组和对象。由于堆内存所存大小不固定,系统无法自动释放回收,所以需要JS引擎来手动释放这些内存

  • 执行上下文:大致分为三类

    a. 全局执行上下文,有一个全局对象window

    b. 函数级上下文:任何一个函数都有自己特有的执行上下文(函数里面的区域可以访问到函数外部的变量,但是函数外部的区域,是访问不到函数里面的)

    c. 块级上下文:由let或者const加一个{}所组成的区域,就是一个块级上下文(括号区域外是无法访问到括号区域里面声明的let或者const变量的,但是可以访问到括号区域里面的var变量)

  • 变量对象:存储某个区块代码里声明的值和变量

  • 真实JS变量在堆栈中的存储:

function foo() {
    var a = 1
    var obj = {
        name: 'xiaoming'
    }
}

foo()
复制代码

  原始类型的值会直接存储在上下文中,而上下文则存储在栈内存中;

  引用类型的值实际上会被存储在堆内存中,每一个值都对应着一个地址,然后在栈内存的执行上下文中将变量的值赋值成对应的地址。 outside_default.png

  • 栈和堆的溢出:

a. 栈:当递归调用方法时,随着栈深度的增加,JVM维持着一条长长的方法调用轨迹,直到内存不够分配,产生栈溢出。

b. 堆:循环创建对象,通俗点就是不断的new一个对象。

26. 调试小技巧

import { cloneDeep } from 'lodash'

// 调试时,由于data是引用类型,在初始化时深层字段可能会发生变化,需要给个快照,记录打印时的真实data值
console.log("this.data", deepClone(this.data))
复制代码

27. map(Number)、map(String)、map(Boolean)的使用

1. 使用map(Number)将数组中的每项数据转换为Number类型

let arr1 = [1, "2", 3]
arr1.map(Number)  // [1, 2, 3]

let arr2 = ['我是cxk', 18]
arr2.map(Number)  // [NaN, 18]

`扩展:判断在函数中传入的Number类型的形参个数`
function getLength(...data) {
  return data.map(Number).filter((num) => num || num === 0).length
}

getLength()   // 0
getLength(1, 2, 'dsadsa', 's', '3')  // 3
 
2. 同样,可以使用map(String)或map(Boolean)将数组中的每项数据转换为String或者Boolean类型
复制代码

28. 细品i = i + x()i = x() + i的区别

`1. i += x()可以转换为i = i + x(), 是先拿i的值, 再执行x()`

let i = 0

function x() { 
  i++ 
  return 10 
} 

i += x() 
console.log(i)  // 输出结果为10

`
解析:
   i += x() 可以转换为i = i + x(), 因为x()是放在i的右边, 还未执行, 所以计算的时候, i的值还未变化。
   因此结果为i = 0 + 10 = 0
`

`2. i = x() + i: 是先执行x(), 再加i`

let i = 0

function x() {
  i++
  return 10
}

i = x() + i
console.log(i)  // 输出结果为11

`
解析:
   i = x() + i, 是先执行x(), 再加i, x()执行后, i的值变为1。
   因此结果为i = 10 + 1 = 11
`
复制代码

29. js偷懒小技巧

`1. 使用array.at()来获取数组元素:索引从0开始,需要传入数字,如果不是数字,会自动转换为数字`

const arr = [1, 3, 5, 6]

`最常用的功能:获取数组的最后一个值`
arr.at(-1) // 6

arr.at(0) // 1
`倒数第二个`
arr.at(-2) // 5
`取不到则为undefined`
arr.at(4) // undefined
arr.at("3123") // undefined
arr.at("大苏打实打实大") // 1
arr.at(NaN) // 1
`传入的如果是正浮点数,则会向下取整`
arr.at(1.4)  // 3
arr.at(1.7) // 3
`传入的如果是负浮点数,则会向上取整`
arr.at(-1.4) // 6
arr.at(-1.8) // 6
arr.at(-0.7) // 1

`2. ??的使用:与或比较类似,区别在于??只有在运算符左侧的值为`null`或`undefined`时,才返回右侧的值,否则返回左侧的值`
0 || 1  // 1
0 ?? 1  // 0
复制代码

30. 变量提升

结语

分享一款前端面试题库 地址:   前端面试题库

posted @ 2022-12-06 18:35  web前端面试小助手  阅读(8)  评论(0)    收藏  举报  来源