ES6考题
1. var、let、const三者区别
-
作用域
var: 函数作用域(Function Scope):var声明的变量只在其所在的函数内有效,如果在函数外部声明,则为全局变量。 let和const: 块作用域(Block Scope):let 和 const 声明的变量只在其所在的代码块(如 if 语句、循环等)内有效。 -
变量提升
var 声明的变量会被提升到函数或全局作用域的顶部,但未初始化的变量在提升时为 undefined。 let 和 const在声明之前不能访问(会导致 ReferenceError),这被称为暂时性死区。 -
重新赋值
var:可以重新赋值。 let:也可以重新赋值。 const:不可重新赋值。声明时必须初始化,之后不能改变其绑定的值(但如果是对象,内部的属性是可以修改的)。const obj = { a:1 } obj.a = 2; //这里可以修改
2. js中什么是可选链操作符
可选链操作符(Optional Chaining Operator)是 JavaScript 中的一种语法,允许你安全地访问对象的深层嵌套属性,而不必显式检查每个级别的存在性。它的语法是 ?.,在访问对象属性时,如果前面的表达式为 null 或 undefined,则整个表达式的结果为 undefined,而不是抛出错误。
语法:
const list = [
{
id:'1',
name:'张三',
address:{
province:'河北省',
city:'张家口',
}
},
{
id:'2',
name:'李四',
address:{
province:'山西省',
city:'太原市',
}
},
{id:'3',name:'王五'}
]
const newList = list.map(item=>{
return item.address.city;//报错
})
const newList = list.map(item=>{
return item.address?.city;//返回:['张家口', '太原市', undefined]
})
3. ES6新增数组方法有哪些
ES6(ECMAScript 2015)引入了一些新的数组方法,使得数组的操作更加方便和高效。以下是一些主要的新增数组方法:
- Array.from() 将类数组对象或可迭代对象转换为数组。
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
const arr = Array.from(arrayLike); // ['a', 'b']
- Array.of() 创建一个新数组实例,使用可变数量的参数作为数组元素。
const arr = Array.of(1, 2, 3); // [1, 2, 3]
- Array.prototype.find() 返回数组中满足提供的测试函数的第一个元素,如果没有找到则返回 undefined。
const numbers = [1, 2, 3, 4, 5];
const found = numbers.find(num => num > 3); // 4
- Array.prototype.findIndex() 返回满足提供的测试函数的第一个元素的索引,如果没有找到则返回 -1。
const numbers = [1, 2, 3, 4, 5];
const index = numbers.findIndex(num => num > 3); // 3
- Array.prototype.fill() 用静态值填充数组的全部或部分元素。
const arr = new Array(5).fill(0); // [0, 0, 0, 0, 0]
- Array.prototype.copyWithin() 在数组内部复制指定位置的元素到另一个位置(可以重叠)。
const arr = [1, 2, 3, 4, 5];
arr.copyWithin(0, 3); // [4, 5, 3, 4, 5]
- Array.prototype.entries() 返回一个新的数组迭代器对象,该对象包含数组中每个索引的键/值对。
const arr = ['a', 'b', 'c'];
const iterator = arr.entries();
for (const [index, value] of iterator) {
console.log(index, value);
}
// 0 'a'
// 1 'b'
// 2 'c'
- Array.prototype.keys() 返回一个新的数组迭代器对象,该对象包含数组中每个索引的键。
const arr = ['a', 'b', 'c'];
const iterator = arr.keys();
for (const key of iterator) {
console.log(key);
}
// 0
// 1
// 2
- Array.prototype.values() 返回一个新的数组迭代器对象,该对象包含数组中每个索引的值。
const arr = ['a', 'b', 'c'];
const iterator = arr.values();
for (const value of iterator) {
console.log(value);
}
// 'a'
// 'b'
// 'c'
- Array.prototype.includes() 判断数组是否包含某个值,返回 true 或 false。
const arr = [1, 2, 3];
console.log(arr.includes(2)); // true
console.log(arr.includes(4)); // false
4. 箭头和普通函数区别
-
this绑定
普通函数:this 的值由调用函数的上下文决定。调用时的上下文会影响 this 的值。this指向可以修改。
箭头函数:this 的值由外层作用域决定,永远指向定义时的 this。this指向不能修改。
var a = '外部'; let obj = { a:'内部', run(){ // return ()=>{ // console.log( this.a ) // } return function(){ console.log( this.a ); } } } obj.run()(); -
构造函数
普通函数:可以用作构造函数,通过 new 关键字创建实例。 箭头函数:不能用作构造函数,不能使用 new 关键字。 -
arguments 对象
普通函数:有 arguments 对象,可以访问调用函数时传入的所有参数。 箭头函数:没有 arguments 对象。如果需要,可以使用剩余参数语法 ...rest。 -
Generator 函数
普通函数:可以使用yield命令,可以当作Generator 函数。 箭头函数:不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
5. map和set区别
-
键/值的唯一性:
Map:键是唯一的,但值可以重复。 Set:值是唯一的,不能重复添加同样的值。 -
存储方式
Set 使用类似于数组的方式存储值。 Map 使用键值对的方式存储数据。
总结:使用场景
Set 适用于需要存储一组唯一值,并且不关心顺序的场景,例如去重、判断元素是否存在等。
Map 适用于需要将值与特定键关联的场景,例如存储键值对的配置信息、构建字典、缓存等。
6. Promise考题
6.1 promise你是怎么理解的
面试回答:
Promise是一个异步编程解决方案,主要解决的就是没有Promise之前的回调函数的问题,因为回调函数可能会出现调用死亡地狱的问题,这样会让我们的代码不好阅读,不好维护,所以诞生Promise来解决此问题,另外Promise本身是对象,Promise.then或catch是属于微任务,而且每一个then都返回一个Promise,Promise就是一个容器,Promise对象代表一个异步操作,其中包含三种状态,进行中、已成功、已失败,当然Promise也有缺点,比如每一个then都是一个单独的作用域,假设在某一个then中定义一个变量在其他then中是无法直接使用的。当然Promise还有更多的方法,比如all、race,在项目中如果多个请求,需要一起返回数据可以用all。
6.2 promise的链式调用是怎么实现的
Promise的链式调用是通过返回Promise对象来实现的。下面是Promise链式调用的基本原理和实现方式:
Promise的基本结构,一个Promise对象有三种状态:
Pending(进行中):初始状态,既不是成功,也不是失败。
Fulfilled(已成功):操作成功完成。
Rejected(已失败):操作失败。
链式调用的实现:链式调用的核心在于then方法。then方法返回一个新的Promise,这允许你在Promise完成后继续调用then方法。
下面是一个简化的Promise实现示例,展示了如何实现链式调用:
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn(value));
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(reason));
}
};
// 执行传入的 executor 函数
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
const handleFulfilled = () => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
};
const handleRejected = () => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (error) {
reject(error);
}
};
if (this.state === 'fulfilled') {
handleFulfilled();
} else if (this.state === 'rejected') {
handleRejected();
} else {
this.onFulfilledCallbacks.push(handleFulfilled);
this.onRejectedCallbacks.push(handleRejected);
}
});
}
}
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('Success!');
}, 1000);
});
promise
.then((result) => {
console.log(result); // 输出 "Success!"
return 'Next success!';
})
.then((result) => {
console.log(result); // 输出 "Next success!"
})
.catch((error) => {
console.error(error);
});
6.3 promise错误捕获有几种方法
方式一:catch
let promise = new Promise((resolve, reject) => {
throw new Error('An error occurred');
});
promise.catch((error) => {
console.error('Error caught:', error);
});
方式二:try...catch
async function asyncFunction() {
try {
throw new Error('An error occurred');
} catch (error) {
console.error('Error caught:', error);
}
}
asyncFunction();
6.4 promise的all和promise的race有什么区别
总结:
Promise.all: 等待所有 Promise 完成,只有在所有 Promise 成功时才会成功。
Promise.race: 返回第一个完成的 Promise,无论其成功或失败。
7. setTimeout、Promise、async/await的区别
一、宏任务、微任务
setTimeout是宏任务
Promise是一个对象,例如then是微任务
async/await是基于 Promise 的高级语法糖,也是微任务
二、使用场景
setTimeout 主要用于定时执行任务,适用于需要在特定时间点执行的操作。
Promise 用于封装异步操作的结果,提供了一种更灵活的方式来处理异步逻辑和错误处理。
async/await 提供了更简洁、更易于理解的异步编程方式,尤其适合处理复杂的异步流程。
8. es6平时用的比较多的有哪些?
let、const命令
变量的解构赋值
字符串的新增方法
箭头函数
数组的新增方法
对象的新增方法
运算符,比如?.
Set 和 Map 数据结构
Promise 对象
包括vue3用到的Proxy
也了解过:Generator函数
当然async/await常用到
Class
Module 的语法