面试题
基础概念
Promise 原理及用法
async/await 原理
es6 Generator 原理
Map 数据结构
Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者基本类型)都可以作为一个键或一个值。
Set 数据结构
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Map 和 Object 的区别
Map 默认不包含任何键,只包含显式插入的键。Object 上会有原型上的键。
Map 的键是有序的,而 Object 的键是无序的。
Map 的键可以是任意值,包括函数、对象或任何基本类型。Object 的键必须是字符串或符号。
Map 的键是唯一的,不会重复。Object 的键是唯一的,如果重复,后面的会覆盖前面的。
Map 的键可以进行迭代,而 Object 的键需要通过 Object.keys() 或 for...of 循环来迭代。
Map 的键值对可以通过 size 属性来获取,而 Object 的键值对需要通过 Object.keys() 或 for...of 循环来获取。
Map 的键值对可以通过 set() 方法来设置,而 Object 的键值对需要通过赋值操作来设置。
Map 的键值对可以通过 get() 方法来获取,而 Object 的键值对需要通过属性访问来获取。
Map 的键值对可以通过 delete() 方法来删除,而 Object 的键值对需要通过 delete
Map 在频繁增删键值对时性能更好,而 Object 在查找键值对时性能更好。
Proxy 和 Reflect
Proxy(代理) 是 ES6 中新增的一个特性。Proxy 让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。 Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与 proxy handler 的方法相同。Reflect 不是一个函数对象,因此它是不可构造的。
与大多数全局对象不同 Reflect 并非一个构造函数,所以不能通过 new 运算符对其进行调用,或者将 Reflect 对象作为一个函数来调用。Reflect 的所有属性和方法都是静态的(就像 Math 对象)。
symbol 数据类型
Symbol 是 ECMAScript 6 引入的一种新的原始数据类型,用来表示独一无二的值。每个 Symbol 值都是唯一的,因此可以用来创建一些独特的标识符。
Symbol 值通过 Symbol 函数生成。
let s = Symbol();
Symbol 函数前不能使用 new 命令,否则会报错。这是因为 Symbol 是原始数据类型,不是对象。
Symbol 作为属性名,该属性不会出现在 for...in、for...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames() 返回。
使用场景:
- 常量的定义
const MY_CONST = Symbol('my_const') - 对象的属性名
const obj = {};
const mySymbol = Symbol("my symbol");
obj[mySymbol] = "hello";
console.log(obj[mySymbol]); // 输出:'hello'
- 定义只读属性
const obj = {};
const mySymbol = Symbol("my symbol");
Object.defineProperty(obj, mySymbol, {
value: "hello",
writable: false,
});
console.log(obj[mySymbol]); // 输出:'hello'
obj[mySymbol] = "world";
console.log(obj[mySymbol]); // 输出:'hello'
- 私有属性
const _myPrivateProp = Symbol("my_private_prop");
class MyClass {
constructor() {
this[_myPrivateProp] = "private value";
}
getPrivateValue() {
return this[_myPrivateProp];
}
}
call、apply、bind 的区别和用法
call 方法可以改变函数的 this 指向,同时还能传递多个参数。
apply 方法和 call 方法类似,它也可以改变函数的 this 指向,但是它需要传递一个数组作为参数列表。
bind 方法和 call、apply 方法不同,它并不会立即调用函数,而是返回一个新的函数,这个新函数的 this 指向被绑定的对象。
let 和 const 与 var 的区别
1、不存在变量提升 必须先定义后使用,否则报错
2、暂时性死区 在代码块内,使用 let 命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
3、不允许重复申明/不允许在函数内部重新申明参数(也算重复申明)
4.1 SE5 的作用域 1)、内层变量覆盖外层的变量 2)、用来 计数的循环变量会泄露为全局变量
5、const 是一个常量,一旦声明,就不能改变。而且在申明的时候必须初始化,不能留到后面赋值。
6、在 ES5 里面,var 在全局作用域下申明的变量,会自动生为 window 的属性: 没法在编译过程爆出变量为申明的错误,语法上顶层对象有一个实体含义的对象这样肯定不合适。 用 var 定义的依然会升级为顶层对象(全局对象)window 的属性;但是 let,const 申明则不会。
js 数据类型
在 JavaScript 中,数据类型可以分为两类:原始类型和对象类型。原始类型包括:数字(number)、字符串(string)、布尔值(boolean)、null、undefined、 Symbol(ES6 新增)和 BigInt,对象类型包括:对象(object)、数组(array)、函数(function)等。
基础类型:数字、字符串、布尔值、null 和 undefined 是 JavaScript 中的五种原始类型,它们都是不可变的。每次对原始类型进行操作时,都会创建一个新的原始类型的值
对象类型: 对象类型则是可变的,因为对象、数组、函数等值是通过引用来访问的
常见数组排序算法
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
- 归并排序
- 堆排序