常见 JavaScript 面试题总结

let 、const、var 的区别

 1. 作用域不同

let 语句声明一个块级作用域的局部变量

const 也是块级范围的,但常量的值无法改变,也不能被重新声明

var 语句声明一个函数范围或全局范围的局部变量

2. 变量提升

let 描述let 声明的变量不会在作用域中被提升,它是在编译时才初始化
const 描述:声明创建一个值的只读引用,变量标识符不能重新分配。 例如,在引用内容是对象的情况下,这意味着可以改变对象的内容

常量一般是大写声明

var 描述:使用 var 声明的变量将在任何代码执行前被创建,这被称为变量提升。这些变量的初始值为 undefined

3. 重复声明

let 不允许重复声明,会抛出 ReferenceError错误 

const 不允许重复声明,会抛出 Identifier 'NAME' has already been declared 错误

var 可以

4. 浏览器兼容性

let 支持 IE 11 以上,火狐安卓版支持 Firefox for Android 44 版本以上

const 同 let 一样

var 都支持

ES6 定义一个长度为8,值为空的数组

new Array(8).fill(null)
// (8) [null, null, null, null, null, null, null, null]

 ES6 数组的扩展主要有:

// 扩展运算符

// Array.from() 将类似数组的对象和可遍历的对象转为真正的数组
Array.from({'0': 'a', '1': 'b', length: 2}) //(2) ['a', 'b']

// Array.of() 将一组值,转换为数组  相当于 [].slice.call(arguments);
Array.of(3, 11, 8, null, undefined) //(5) [3, 11, 8, null, undefined]

// 实例方法:copyWithin() 将指定位置的成员复制到其他位置,返回当前数组
['a', 'b', 'c', 'd', 'e'].copyWithin(1, 4)
//(5) ['a', 'e', 'c', 'd', 'e'] 把 b 替换成 e

// find() 找到符合条件的成员,返回该成员,没有符合的成员返回undefined
[1, 2, 3].find(v => { return v  === 3}) // 3
[1, 2, 3].find(v => { return v  === 6}) // undefined

// findIndex() 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
[1, 2, 3].findIndex(v => { return v  === 3}) // 2

// findLast() 从数组的最后一个位置开始查
[1, 2, 3].findLast(v => { return v  === 3}) // 3

// findLastIndex() 从数组的最后一个成员开始,依次向前检查 返回位置索引
[1, 2, 3].findLastIndex(v => { return v  === 1}) // 0

// 实例方法:fill(value, startIndex,endIndex) 给定一个值 填充数组
new Array(3).fill(7) //[7, 7, 7]
new Array(5).fill(7, 3, 4) //(5) [empty × 3, 7, empty]

// entries() 遍历键值对
// keys() 遍历键名
// values() 遍历键值

// includes() 返回一个布尔值,表示摸个数组是否包含给定的值
[1, 2, 3].includes(2) // true

// flat(拉平的层数) 用于将嵌套的数组“拉平”
[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
[1, 2, [3, 4, [5, 6]]].flat(3) // (6) [1, 2, 3, 4, 5, 6]

// flatMap() 对原数组的每个成员执行一个函数,然后对返回值组成的数组执行flat()方法
[2, 3, 4].flatMap((x) => [x, x * 2]) //(6) [2, 4, 3, 6, 4, 8]

// at() 返回对应位置的成员,并支持负索引
['a', 'b', 'c'].at(2) // 'c'

// toReversed() 颠倒数组成员的位置
[1, 2, 3].toReversed() //(3) [3, 2, 1]

// toSorted() 用来对数组成员排序
[1, 3, 2].toSorted() //(3) [1, 2, 3]

// toSpliced() 用来在指定位置,删除指定数量的成员,并插入新成员
['a', 'b', 'c', 'd'].toSpliced(1, 2, 'bb', 'cc', 'dd') // ['a', 'bb', 'cc', 'dd', 'd']

// with(index, value) 将指定位置的成员替换为新的值
['a', 'b', 'c', 'd'].with(2, 4) // ['a', 'b', 4, 'd']

js 的数据类型

javascript 数据类型分为基本数据类型(值类型)和复杂数据类型(引用类型)

值类型是保存在栈(先进后出)里面的,引用类型时保存在堆(先进先出)里面的

常见的基本数据类型有:

Number、String、Boolean、Null、undefined、symbol、BigInt

常见的复杂数据类型有:

Object、Array、Function、Date、RegExp

箭头函数的几个特性

  1. 箭头函数内部继承外部作用域。没有独立作用域。在普通函数里this指向obj作用域, 箭头函数里this指向windows对象。
  2. 箭头函数不能用作构造函数
  3. 箭头函数没有prototype属性。箭头函数的prototype指向undefined

闭包及闭包的运用场景

闭包概念:闭包就是能够读取其他函数内部变量的函数

运用场景:

        1、可以读取函数内部的变量

        2、让变量的值始终保持在内存中,不会在函数调用后自动清除

缺点:

        1、内存泄漏

        2、可能会改变父函数内部变量的值

typeof 和 instanceof 的区别

typeof 一般用于测试基本操作类型,操作符返回一个字符串,表示未经计算的操作数的类型

instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。

for in 和 for of 的区别

for...in 语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

for...of 语句在可迭代对象(包括 ArrayMapSetStringTypedArrayarguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

大致就是前者只能作用于对象,用来遍历对象属性,后者作用比较广,详细参考for...of详解

Set 和 Map 的区别

Set  类似于数组,是一个构造函数,用来生成 Set 数据结构,成员的值都是唯一的

Map 类似于对象,是键值对集合,但是键的范围可以是各种类型(包括对象)属性

 Map 属性:

        1. size 属性,返回Map结构成员总数

 Map 方法:

  1. set() 设置对应key为value
  2. get() 读取对应key,找不到返回undefined
  3. has() 返回一个布尔值
  4. delete() 删除某个键,返回true/false
  5. clear() 清除所有成员,没有返回值

浅拷贝和深拷贝

基本类型 =》拷贝的是基本类型的值,引用类型 =》拷贝的是内存地址

浅拷贝只复制属性指向某个对象的指针,新旧对象还共享同一块内存,修改会影响原对象

深拷贝创造一个一模一样的对象,不共享内存

浅拷贝常用方法:

  1. object.assign(),不会拷贝对象的继承属性,不会拷贝不可枚举的属性
  2. Array.prototype.slice()
  3. Array.prototype.concat()
  4. 拓展运算符

深拷贝常用方法:

  1. Lodash 库中 _.cloneDeep() 方法
  2. JSON.stringify(),会忽略undefined、symbol和函数
  3. jQuery.extend()
  4. 循环递归

数组常用方法

会改变原数组的方法:

  1. push 向末尾添加一个元素
  2. pop 删除数组最后一个元素
  3. shift 删除第一个元素
  4. unshift 向开头添加一个元素
  5. reverse 倒叙,不会创建新数组
  6. sort 在原数组上进行排序
  7. splice 添加或者删除数组

 不会改变原数组的方法:

  1. forEach 为每个数组元素调用函数
  2. every
  3. same
  4. reduce
  5. find
  6. findIndex
  7. filter
  8. concat
  9. join
  10. keys
  11. includes
  12. from 从对象创建数组
  13. slice 选择数组的一部分
  14. toString
  15. entries 返回键/值对数组迭代对象
  16. map 使用为每个元素调用的函数返回新数组
  17. valueOf 返回数组的原始值

常用算法排序

数组排序 

1.冒泡排序:依次比较相邻的元素,如果顺序错误就交换,直到没有相邻元素需要交换

function bubbleSort(arr){
    let i = j = 0;
    for(i = 1; i < arr.length; i++) {
        for(let j = 0; j<=arr.length - i; j++) {
            let temp = 0;
            if(arr[j] > arr[j+1]) {
                temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp            
            }        
        }    
    }
    return arr
}

 2.快速排序,描述如下:

  1. 设定一个分界值,将数组分成两部分
  2. 将大于分界值的集中到数组右边,小于分界值的集中到数组左边
  3. 然后,左边和右边可以独立排序,对于左侧的数据,又可以取一个分界值
  4. 通过递归调用,然后实现快速排序
  function quickSort(ary) {
    if (ary.length <= 1) {
      return ary;
    }
    //2.如果长度不为1,那么就取数组的中间值
    let contentIndex = Math.floor(ary.length / 2);
    let contentValue = ary.splice(contentIndex, 1)[0];
    //3.先定义左右两个数组,然后让数组中剩余的数与中间数进行比较,比中间数小的放到左边的数组,比中间数大的放到右边的数组。
    let leftArr = [];
    let rightArr = [];
    for (let i = 0; i < ary.length; i++) {
      let item = ary[i];
      item > contentValue ? rightArr.push(item) : leftArr.push(item);
    }
    //4.使用递归的方式让左右两边的数组持续这样处理,直至左右两边的数组都排好序,最后三者进行拼接
    return quickSort(leftArr).concat(contentValue, quickSort(rightArr));
  }

3. 插入排序

4. 二路归并: 将两个按值有序序列合并成一个按值有序序列,称为二路归并排序

常见其他算法

1. 阶乘:非递归实现、递归实现

 2. 生成斐波那契数列:强行递归实现、简约非递归版

 3. 二分查找:非递归实现、递归实现

enumerable 对象的可枚举属性

描述对象的 enumerable 属性,称为“可枚举性”,如果该属性为 false,就表示某些操作会忽略当前属性

目前只有四个操作会忽略 enumerable 为 false 的属性

 1. for...in 循环:只遍历对象自身的和继承的可枚举的属性

2. Object.keys():返回对象自身的所有可枚举的属性的键名

3. JSON.stringify():只串行化对象自身的可枚举的属性

4. Object.assign():只拷贝对象自身的可枚举的属性 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值