2024-08-14
前端
00

目录

var,let,const的区别
使用箭头函数的注意事项
模板字符串
基本语法
多行字符串
表达式插值
嵌套模板字符串
标签模板(Tagged Templates)
原始字符串(Raw Strings)
set map的区别
1. 定义和用途
Promise相关
Promise 的三种状态
何时会进入 catch

var,let,const的区别

  • var可以重复声明,let不可以重复声明
  • var不受限于块级,let受限于块级
  • var会跟window相映射
  • const声明后必须赋值,赋值后不可修改
  • var可以在声明的上方访问变量,let不可

使用箭头函数的注意事项

  1. this不再指向window,而是指向父级
  2. 不能使用arguments
  3. 不能用作构造函数
  4. 不能使用yield命令

模板字符串

ES6 中引入的模板字符串(Template Literals),又称模板字面量,是一种提供了更强大和灵活的字符串操作功能的语法。与传统的字符串拼接方式相比,模板字符串更为简洁和易读,特别是在需要插入变量、多行字符串或进行复杂操作时。

基本语法

模板字符串使用反引号(`)来定义,而不是传统的单引号(')或双引号(")。在模板字符串中,可以直接嵌入表达式、变量或函数的返回值,使用 ${} 语法。

示例:

javascript
const name = 'John'; const age = 30; const greeting = `Hello, my name is ${name} and I am ${age} years old.`; console.log(greeting); // 输出: Hello, my name is John and I am 30 years old.

多行字符串

在传统的 JavaScript 中,要创建多行字符串,通常需要使用字符串拼接或转义字符 \n。而在模板字符串中,直接回车换行即可实现多行字符串,非常直观。

示例:

javascript
const multiLineString = `This is a string that spans across multiple lines.`; console.log(multiLineString); /* 输出: This is a string that spans across multiple lines. */

表达式插值

模板字符串不仅可以嵌入变量,还可以在 ${} 中直接执行表达式,包括算术运算、函数调用、三元运算符等。

示例:

javascript
const a = 10; const b = 20; const sum = `The sum of a and b is ${a + b}.`; console.log(sum); // 输出: The sum of a and b is 30.

嵌套模板字符串

在模板字符串内部,也可以嵌套其他的模板字符串,从而实现更复杂的字符串构建。

示例:

javascript
const user = { name: 'Alice', age: 25, }; const greeting = `Hello, ${user.name}. You are ${user.age} years old, which is ${user.age >= 18 ? 'an adult' : 'not an adult'}.`; console.log(greeting); // 输出: Hello, Alice. You are 25 years old, which is an adult.

标签模板(Tagged Templates)

标签模板是一种高级用法,允许在模板字符串的生成过程中调用一个函数,并且将模板字符串中的字符串部分和表达式部分分别传递给该函数进行处理。

语法:

javascript
function tag(strings, ...values) { // strings 是一个数组,包含模板字符串中的静态文本部分 // values 是一个数组,包含插值表达式的值 return `${strings[0]}${values[0]}${strings[1]}${values[1]}...`; } const name = 'John'; const age = 30; const result = tag`Name: ${name}, Age: ${age}`; console.log(result); // 输出由 tag 函数定义的结果

示例:

javascript
function highlight(strings, ...values) { return strings.reduce((result, str, i) => { return `${result}${str}<span class="highlight">${values[i] || ''}</span>`; }, ''); } const name = 'John'; const age = 30; const result = highlight`Name: ${name}, Age: ${age}`; console.log(result); // 输出: Name: <span class="highlight">John</span>, Age: <span class="highlight">30</span>

原始字符串(Raw Strings)

模板字符串中的特殊字符,如换行符或反斜杠,通常会被自动处理。如果需要获取原始的未转义字符串,可以使用 String.raw 标签函数。

示例:

javascript
const path = String.raw`C:\Development\project\file.txt`; console.log(path); // 输出: C:\Development\project\file.txt

set map的区别

在 JavaScript 中,SetMap 是两种新引入的数据结构,分别用于存储独特的值和键值对。虽然它们都有一些相似之处,比如都能存储任意类型的数据并且是可迭代的,但它们在用途和操作上有很大的区别。以下是 SetMap 的详细比较:

1. 定义和用途

  • Set

    • Set 是一种数据结构,用于存储唯一的值。它类似于数组,但不同的是 Set 中的每个值都是唯一的,不能重复。
    • 常用于存储一组无重复的元素,或者用于移除数组中的重复项。
    javascript
    const set = new Set([1, 2, 3, 4, 4]); // 重复的 4 只会存储一次 console.log(set); // 输出: Set { 1, 2, 3, 4 }
  • Map

    • Map 是一种数据结构,用于存储键值对。与普通对象不同,Map 的键可以是任意类型,包括对象、函数、基本类型等。
    • 常用于存储与某个键关联的值,特别是在需要使用复杂键(如对象)时。
    javascript
    const map = new Map(); map.set('name', 'John'); map.set({ key: 'age' }, 30); console.log(map); // 输出: Map { 'name' => 'John', { key: 'age' } => 30 }

2. 键与值

  • Set

    • Set 中只存储值,没有键。每个值都是唯一的,不允许重复。
    • Set 的值可以是任意类型,包括对象、函数、基本类型等。
    javascript
    const set = new Set(); set.add(1); set.add(2); set.add(1); // 重复的值不会添加 console.log(set); // 输出: Set { 1, 2 }
  • Map

    • Map 中存储的是键值对,每个键都是唯一的。
    • 键可以是任意类型,包括对象、函数、基本类型等,且与其关联的值也可以是任意类型。
    javascript
    const map = new Map(); map.set('key1', 'value1'); map.set({}, 'value2'); console.log(map); // 输出: Map { 'key1' => 'value1', {} => 'value2' }

3. 常用方法和属性

  • Set

    • add(value):向 Set 中添加一个值。
    • delete(value):从 Set 中删除指定值。
    • has(value):检查 Set 中是否存在某个值。
    • clear():清空 Set 中的所有值。
    • size:返回 Set 中值的个数。
    javascript
    const set = new Set(); set.add(1); set.add(2); console.log(set.has(1)); // 输出: true set.delete(1); console.log(set.size); // 输出: 1 set.clear(); console.log(set.size); // 输出: 0
  • Map

    • set(key, value):向 Map 中添加或更新一个键值对。
    • get(key):返回 Map 中与指定键关联的值。
    • delete(key):从 Map 中删除指定键对应的键值对。
    • has(key):检查 Map 中是否存在某个键。
    • clear():清空 Map 中的所有键值对。
    • size:返回 Map 中键值对的个数。
    javascript
    const map = new Map(); map.set('key1', 'value1'); map.set('key2', 'value2'); console.log(map.get('key1')); // 输出: value1 map.delete('key1'); console.log(map.has('key1')); // 输出: false console.log(map.size); // 输出: 1 map.clear(); console.log(map.size); // 输出: 0

4. 迭代

  • Set

    • Set 是可迭代的,可以使用 for...of 循环直接遍历它的值。
    • 提供了 keys()values()entries() 方法,但 keys()values() 返回相同的迭代器(因为 Set 没有键)。
    javascript
    const set = new Set([1, 2, 3]); for (let value of set) { console.log(value); } // 输出: // 1 // 2 // 3
  • Map

    • Map 也是可迭代的,可以使用 for...of 循环直接遍历它的键值对。
    • 提供了 keys()values()entries() 方法,分别用于获取键、值和键值对的迭代器。
    javascript
    const map = new Map([['key1', 'value1'], ['key2', 'value2']]); for (let [key, value] of map) { console.log(`${key} = ${value}`); } // 输出: // key1 = value1 // key2 = value2

5. 性能考虑

  • Set
    • 在处理大量去重操作或需要快速查找某个元素时,Set 通常比数组更有效率。
  • Map
    • 在处理大量键值对,特别是需要复杂键(如对象)时,Map 比对象更高效且更直观。

Promise相关

在 JavaScript 中,Promise 是一种用于处理异步操作的对象。Promise 对象代表了一个异步操作的最终结果,它有三种状态:

Promise 的三种状态

  1. pending(待定状态)

    • 初始状态,表示 Promise 还未完成,也未被拒绝。在这个状态下,异步操作尚未完成,Promise 的结果未知。
    • 处于 pending 状态的 Promise 会等待异步操作的结果,直到状态转换为 fulfilledrejected
  2. fulfilled(已成功状态)

    • 表示异步操作成功完成,Promise 被解决(resolved)。在这个状态下,Promise 会携带操作成功的结果值。
    • Promise 状态变为 fulfilled 时,then 方法中注册的成功回调函数(第一个参数)会被调用。
  3. rejected(已拒绝状态)

    • 表示异步操作失败,Promise 被拒绝(rejected)。在这个状态下,Promise 会携带操作失败的原因(通常是一个错误对象)。
    • Promise 状态变为 rejected 时,catch 方法(或 then 方法的第二个参数)中的回调函数会被调用。

何时会进入 catch

catch 方法是用来处理 Promise 被拒绝的情况,也就是说,当 Promise 状态变为 rejected 时,catch 方法会被调用。

以下是一些典型的场景,Promise 会进入 catch

  1. 显式拒绝(调用 reject

    • 当你在 Promise 构造函数中的异步操作遇到错误时,调用 reject 函数来拒绝 Promise
    javascript
    const promise = new Promise((resolve, reject) => { const success = false; if (!success) { reject('Operation failed'); } }); promise.catch(error => { console.error(error); // 输出: Operation failed });
  2. 抛出异常

    • 如果在 Promise 构造函数的同步代码或 then 方法的回调函数中抛出了一个错误或异常,Promise 将自动捕获这个错误并将状态变为 rejected,从而触发 catch
    javascript
    const promise = new Promise((resolve, reject) => { throw new Error('Something went wrong'); }); promise.catch(error => { console.error(error); // 输出: Error: Something went wrong });
  3. 链式调用中的错误

    • 如果在 then 链式调用中的某一个 then 回调函数抛出异常,后续的 catch 会捕获这个错误。
    javascript
    const promise = new Promise((resolve) => { resolve('Success'); }); promise .then(result => { console.log(result); // 输出: Success throw new Error('Error in then'); }) .catch(error => { console.error(error); // 输出: Error: Error in then });
  4. 返回的 Promise 被拒绝

    • 如果 then 回调函数中返回的 Promise 最终被拒绝,后续的 catch 也会捕获这个错误。
    javascript
    const promise = new Promise((resolve) => { resolve('Initial success'); }); promise .then(result => { return new Promise((resolve, reject) => { reject('Failure in second promise'); }); }) .catch(error => { console.error(error); // 输出: Failure in second promise });

总结

  • Promise 有三种状态:pending(待定)、fulfilled(已成功)、rejected(已拒绝)。
  • Promise 会在以下情况进入 catch
    1. 显式调用 reject
    2. 构造函数或回调函数中抛出异常。
    3. 链式调用中的某个 then 回调函数抛出异常。
    4. then 回调函数中返回的 Promise 被拒绝。

使用 catch 方法可以有效处理异步操作中的错误和异常,确保代码在面对不可预见的错误时能够稳健地运行。

本文作者:Jeff Wu

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!