ES6 中引入的模板字符串(Template Literals),又称模板字面量,是一种提供了更强大和灵活的字符串操作功能的语法。与传统的字符串拼接方式相比,模板字符串更为简洁和易读,特别是在需要插入变量、多行字符串或进行复杂操作时。
模板字符串使用反引号(`)来定义,而不是传统的单引号(')或双引号(")。在模板字符串中,可以直接嵌入表达式、变量或函数的返回值,使用 ${} 语法。
示例:
javascriptconst 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。而在模板字符串中,直接回车换行即可实现多行字符串,非常直观。
示例:
javascriptconst multiLineString = `This is a string
that spans across
multiple lines.`;
console.log(multiLineString);
/*
输出:
This is a string
that spans across
multiple lines.
*/
模板字符串不仅可以嵌入变量,还可以在 ${} 中直接执行表达式,包括算术运算、函数调用、三元运算符等。
示例:
javascriptconst 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.
在模板字符串内部,也可以嵌套其他的模板字符串,从而实现更复杂的字符串构建。
示例:
javascriptconst 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.
标签模板是一种高级用法,允许在模板字符串的生成过程中调用一个函数,并且将模板字符串中的字符串部分和表达式部分分别传递给该函数进行处理。
语法:
javascriptfunction 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 函数定义的结果
示例:
javascriptfunction 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>
模板字符串中的特殊字符,如换行符或反斜杠,通常会被自动处理。如果需要获取原始的未转义字符串,可以使用 String.raw 标签函数。
示例:
javascriptconst path = String.raw`C:\Development\project\file.txt`;
console.log(path); // 输出: C:\Development\project\file.txt
在 JavaScript 中,Set 和 Map 是两种新引入的数据结构,分别用于存储独特的值和键值对。虽然它们都有一些相似之处,比如都能存储任意类型的数据并且是可迭代的,但它们在用途和操作上有很大的区别。以下是 Set 和 Map 的详细比较:
Set:
Set 是一种数据结构,用于存储唯一的值。它类似于数组,但不同的是 Set 中的每个值都是唯一的,不能重复。javascriptconst set = new Set([1, 2, 3, 4, 4]); // 重复的 4 只会存储一次
console.log(set); // 输出: Set { 1, 2, 3, 4 }
Map:
Map 是一种数据结构,用于存储键值对。与普通对象不同,Map 的键可以是任意类型,包括对象、函数、基本类型等。javascriptconst map = new Map();
map.set('name', 'John');
map.set({ key: 'age' }, 30);
console.log(map); // 输出: Map { 'name' => 'John', { key: 'age' } => 30 }
Set:
Set 中只存储值,没有键。每个值都是唯一的,不允许重复。Set 的值可以是任意类型,包括对象、函数、基本类型等。javascriptconst set = new Set();
set.add(1);
set.add(2);
set.add(1); // 重复的值不会添加
console.log(set); // 输出: Set { 1, 2 }
Map:
Map 中存储的是键值对,每个键都是唯一的。javascriptconst map = new Map();
map.set('key1', 'value1');
map.set({}, 'value2');
console.log(map); // 输出: Map { 'key1' => 'value1', {} => 'value2' }
Set:
add(value):向 Set 中添加一个值。delete(value):从 Set 中删除指定值。has(value):检查 Set 中是否存在某个值。clear():清空 Set 中的所有值。size:返回 Set 中值的个数。javascriptconst 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 中键值对的个数。javascriptconst 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
Set:
Set 是可迭代的,可以使用 for...of 循环直接遍历它的值。keys()、values() 和 entries() 方法,但 keys() 和 values() 返回相同的迭代器(因为 Set 没有键)。javascriptconst set = new Set([1, 2, 3]);
for (let value of set) {
console.log(value);
}
// 输出:
// 1
// 2
// 3
Map:
Map 也是可迭代的,可以使用 for...of 循环直接遍历它的键值对。keys()、values() 和 entries() 方法,分别用于获取键、值和键值对的迭代器。javascriptconst map = new Map([['key1', 'value1'], ['key2', 'value2']]);
for (let [key, value] of map) {
console.log(`${key} = ${value}`);
}
// 输出:
// key1 = value1
// key2 = value2
Set:
Set 通常比数组更有效率。Map:
Map 比对象更高效且更直观。在 JavaScript 中,Promise 是一种用于处理异步操作的对象。Promise 对象代表了一个异步操作的最终结果,它有三种状态:
pending(待定状态):
Promise 还未完成,也未被拒绝。在这个状态下,异步操作尚未完成,Promise 的结果未知。pending 状态的 Promise 会等待异步操作的结果,直到状态转换为 fulfilled 或 rejected。fulfilled(已成功状态):
Promise 被解决(resolved)。在这个状态下,Promise 会携带操作成功的结果值。Promise 状态变为 fulfilled 时,then 方法中注册的成功回调函数(第一个参数)会被调用。rejected(已拒绝状态):
Promise 被拒绝(rejected)。在这个状态下,Promise 会携带操作失败的原因(通常是一个错误对象)。Promise 状态变为 rejected 时,catch 方法(或 then 方法的第二个参数)中的回调函数会被调用。catchcatch 方法是用来处理 Promise 被拒绝的情况,也就是说,当 Promise 状态变为 rejected 时,catch 方法会被调用。
以下是一些典型的场景,Promise 会进入 catch:
显式拒绝(调用 reject):
Promise 构造函数中的异步操作遇到错误时,调用 reject 函数来拒绝 Promise。javascriptconst promise = new Promise((resolve, reject) => {
const success = false;
if (!success) {
reject('Operation failed');
}
});
promise.catch(error => {
console.error(error); // 输出: Operation failed
});
抛出异常:
Promise 构造函数的同步代码或 then 方法的回调函数中抛出了一个错误或异常,Promise 将自动捕获这个错误并将状态变为 rejected,从而触发 catch。javascriptconst promise = new Promise((resolve, reject) => {
throw new Error('Something went wrong');
});
promise.catch(error => {
console.error(error); // 输出: Error: Something went wrong
});
链式调用中的错误:
then 链式调用中的某一个 then 回调函数抛出异常,后续的 catch 会捕获这个错误。javascriptconst 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
});
返回的 Promise 被拒绝:
then 回调函数中返回的 Promise 最终被拒绝,后续的 catch 也会捕获这个错误。javascriptconst 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:
reject。then 回调函数抛出异常。then 回调函数中返回的 Promise 被拒绝。使用 catch 方法可以有效处理异步操作中的错误和异常,确保代码在面对不可预见的错误时能够稳健地运行。
本文作者:Jeff Wu
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!