es6

模板字符串
ES6 中的模板字符串(template string)是一种增强版的字符串,用反引号(`)标识。模板字符串使得字符串的拼接和处理更加方便、灵活和易读,尤其在涉及多行文本和动态内容插入的情况下,可以减少代码的复杂性和冗余度。

let job = "程序员",

salary = "100";

let say = `现在${job}, ${salary}`;
解构赋值
ES6 中的解构赋值是一种方便的数据提取和赋值方式,它允许从数组或对象中提取值,并将其赋给变量。

数组的解构赋值

let [a, b, c] = [1, 2, 3];

console.log(a); // 1

console.log(b); // 2

console.log(c); // 3



// 可以跳过某些位置

let [x, , z] = [4, 5, 6];

console.log(x); // 4

console.log(z); // 6



// 可以使用剩余操作符 `...` 收集剩余的元素

let [m, n, ...rest] = [7, 8, 9, 10, 11];

console.log(m); // 7

console.log(n); // 8

console.log(rest); // [9, 10, 11]
对象的解构赋值

let { name, age } = { name: "John", age: 30 };

console.log(name); // John

console.log(age); // 30



// 可以给变量起不同的名字

let { name: myName, age: myAge } = { name: "Jane", age: 25 };

console.log(myName); // Jane

console.log(myAge); // 25



// 可以设置默认值

let { city = "New York" } = {};

console.log(city); // New York
扩展运算符
ES6 的扩展运算符(...)是一种方便的操作符,它主要有以下功能:

展开数组或对象

console.log(...[1, 2, 3]); // 输出:1 2 3

console.log(1, ...[2, 3, 4], 5); // 输出:1 2 3 4 5



let obj1 = { foo: "bar", x: 42 };

let clonedObj = { ...obj1 };

console.log(clonedObj); // 输出:{ foo: "bar", x: 42 }
数组拷贝

let arr = [1, 2, [3, 4]];

let arr1 = [...arr];

arr1[2].push(5);

console.log(arr); // 输出:[1, 2, [3, 4, 5]]

console.log(arr1); // 输出:[1, 2, [3, 4, 5]]
合并数组或对象

var arr1 = [0, 1, 2];

var arr2 = [3, 4, 5];

var arr3 = [...arr1, ...arr2];

console.log(arr3); // 输出:[0, 1, 2, 3, 4, 5]
函数参数传递

function sum(x, y, z) {

return x + y + z;

}

const numbers = [1, 2, 3];

console.log(sum(...numbers)); // 输出:6
与解构赋值结合

const [first, ...rest] = [1, 2, 3, 4, 5];

console.log(first); // 输出:1

console.log(rest); // 输出:[2, 3, 4, 5]
字符串转字符数组

const title = "china";

const charts = [...title];

console.log(charts); // 输出:['c', 'h', 'i', 'n', 'a']
数组去重(结合 Set)

const arrayNumbers = [1, 5, 9, 3, 5, 7, 10, 4, 5, 2, 5];

const newNumbers = [...new Set(arrayNumbers)];

console.log(newNumbers); // 输出:[1, 5, 9, 3, 7, 10, 4, 2]
 剩余参数
ES6 中的剩余参数语法允许将不定数量的参数表示为一个数组。

其语法形式为:在函数的最后一个命名参数前加上三个点(...),后面跟着参数名,例如:function(a, b,...theArgs){ // 函数体 } ,在这个例子中,theArgs 将收集该函数的第三个参数及以后的所有剩余参数。

function fun1(...theArgs) {

alert(theArgs.length);

}

fun1(); // 弹出"0", 因为 theArgs 没有元素

fun1(5); // 弹出"1", 因为 theArgs 只有一个元素

fun1(5, 6, 7); // 弹出"3", 因为 theArgs 有三个元素



function multiply(multiplier,...theArgs) {

return theArgs.map(function(element) {

return multiplier * element;

});

}

var arr = multiply(2, 1, 2, 3);

console.log(arr); // (2, 4, 6)



function sortRestArgs(...theArgs) {

var sortedArgs = theArgs.sort();

return sortedArgs;

}

alert(sortRestArgs(5, 3, 7, 1)); // 弹出 1, 3, 5, 7



// 剩余参数可以被解构

function f(...(a, b, c)) {

return a + b + c;

}

f(1) // NaN (b 和 c 是 undefined)

f(1, 2, 3) // 6

f(1, 2, 3, 4) // 6 (第四个参数没有被解构)

ES6 引入了类(class)的概念,使面向对象编程在 JavaScript 中更加清晰和直观。

 模块化
ES6 引入了模块化的概念,这使得 JavaScript 代码的组织和管理更加清晰和高效。

一个模块就是一个独立的 JavaScript 文件。模块内的变量、函数、类等默认是私有的,只有通过 export 关键字导出的部分才能被其他模块使用。

导出

// 导出单个变量或函数

export const num = 42;

export function add(a, b) {

return a + b;

}



// 也可以将多个导出写在一处

const str = "Hello";

function subtract(a, b) {

return a - b;

}

export { str, subtract };
导入

import { num, add } from "./module1";
 promise

1. Promise 由来
在以前我们实现异步是用的回调函数,当一个异步请求需要依赖上一个异步请求返回的结果的时候,就会形成如下这种的调用结构。

请求1(function (结果1) {
请求2(function (结果2) {
请求3(function(结果3)) {
请求4(function(结果4) {})
}
});
});
这种结构看着很杂乱且不易维护,被我们亲切的叫做 “回调地狱”。为了解决回调地狱的问题,Promise 就诞生了。

Promise 诞生的使命:优雅的去表示异步回调。

2. Promise 基础概念
2.1 创建 promise 实例
Promise 是一个构造函数,所以我们在调用一个 Promsie 的时候,要用 new Promsie 的方式去调用。

const ps = new Promise();
new Promise 接受一个函数类型的参数。这个函数又接收两个参数 resolve 和 reject,分别对映成功回调和失败回调。Promise 内部有 3 种状态 pending(进行时),fulfilled(已成功),rejected(已失败)。且这三种状态是不可逆的,只能由 pending 到 fulfilled,pending 到 rejected。resolve 使 promise 状态由 pending 到 fulfilled,reject 使 promise 状态由 pending 到 rejected。

const ps = new Promise(function () {});

const ps = new Promise(function (resolve, reject) {
let number = 10;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});

2.2 实例方法
为了更好的控制下一步执行,又诞生了三个实例方法 then、catch、finally。

2.2.1 then 方法
then 方法一般接受两个参数 resolve、reject。分别对应成功时的回调和失败时的回调。

成功状态的 promise 实例
const ps1 = new Promise(function (resolve, reject) {
let number = 10;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});

ps1.then(function (res) {
console.log(res);
});


失败状态的 promise 实例
const ps2 = new Promise(function (resolve, reject) {
let number = 9;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});

ps2.then(
function (res) {},
function (err) {
console.log(err);
}
);


2.2.2 catch 方法
then 方法支持链式调用,then 的执行严重依赖上一步的结果,上一步如果没有结果,那么下一步就不会执行。但是每一步都写 reject 特别麻烦,所以诞生了 catch,then 就可以省略 reject 方法,reject 方法就交给 catch 执行,同时 catch 还可以捕获执行 resolve 的异常。

const ps2 = new Promise(function (resolve, reject) {
let number = 9;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});

ps2
.then(function (res) {})
.catch(function (err) {
console.log(err);
});
2.2.3 finally 方法
有的时候,无论成功还是失败都需要执行一些操作,就诞生了 finally。我们可以在这做一些清理工作。

const ps2 = new Promise(function (resolve, reject) {
let number = 9;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});

ps2
.then(function (res) {})
.catch(function (err) {
console.log(err);
})
.finally(function () {
console.log("end");
});


2.2.4 then 的链式调用
因为 then 方法支持链式调用,所以我们需要知道使用 then 方法会有什么效果。只要调用 promise 实例的 then 方法一定产生一个新的 promise,这个 promise 的状态由里面的函数决定。函数什么时候有结果,这个新 promise 状态什么时候由 pending 转 fulfilled。catch 和 finally 同理。

const ps = new Promise(function (resolve, reject) {
let number = 10;
if (number >= 10) {
resolve(number);
} else {
reject("number 小于10");
}
});

ps.then(function (res) {
return res * 10;
})
.then(function (res) {
return res + 2;
})
.then(function (res) {
if (res > 100) {
console.log(res);
} else {
console.log("最后结果小于100");
}
});


3. Promise 原型方法
为了满足更多的业务需要,又诞生了 6 个原型方法 Promise.all()、Promise.allSettled()、Promise.any()、Promise.race()、Promise.reject()、Promise.resolve()。且都会返回一个确定状态的 Promsie 对象。

统一使用两个成功异步 ps1、ps2。两个失败异步 ps3、ps4。作为测试用例。如下:

const ps1 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("成功结果1");
}, 1000);
});

const ps2 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("成功结果2");
}, 2000);
});

const ps3 = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("失败结果1");
}, 3000);
});

const ps4 = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("失败结果2");
}, 2000);
});
3.1 Promise.all()
通过数组的形式传入异步操作,所有的异步执行都成功,才执行成功,如果有一个失败了,就执行失败。例子如下:

都成功,执行 then 方法,成功返回结果,通过 res 以数组的方式返回

Promise.all([ps1, ps2])
.then(function (res) {
console.log("都成功", res);
})
.catch(function (err) {
console.log(err);
});


按传入顺序执行,如果有一个异步执行失败,中断其他异步操作,执行 catch 方法,通过 err 返回失败结果

Promise.all([ps1, ps2, ps3, ps4])
.then(function (res) {
console.log("都成功", res);
})
.catch(function (err) {
console.log("执行失败", err);
});


3.2 Promise.allSettled()
所有执行都有结果了就执行,无论成功还是失败

Promise.allSettled([ps1, ps2, ps3, ps4]).then(function (res) {
console.log("都返回结果", res);
});


3.3 Promise.any()
任意异步成功了就执行

Promise.any([ps1, ps2, ps3, ps4]).then(function (res) {
console.log("任意成功", res);
});


3.4 Promise.race()
任意异步成功或失败就执行。

Promise.race([ps1, ps2, ps3, ps4]).then(function (res) {
console.log("任意成功或失败", res);
});


3.5 Promise.reject()
返回一个状态为 rejected 的 Promise 对象

 

3.6 Promise.resolve()
会接收 4 种类型的参数:promise 实例 、具有 then 方法的对象、没有 then 方法的对象、不传参

当参数是一个 Promise 实例时,直接返回这个实例。

Promise.resolve(ps1);


当参数是一个具有 then 方法的对象时,将这个对象转为 Promise 对象,并立即执行对象的 then 方法

let obj = {
name: "yqcoder",
then(resolve) {
resolve(this.name);
},
};

Promise.resolve(obj);


当参数是一个没有 then 方法的对象,或者参数不是对象时,就会返回状态为 fulfilled 的新的 Promise 对象,并将参数传入下一个 then。

let obj = {
name: "yqcoder",
};

let ps = Promise.resolve(obj);

ps.then(function (res) {
console.log("结果", res);
});

当不带任何参数时,就会返回一个状态为 fulfilled 的 Promise 对象

Promise.resolve();

 map/set
在 ES6 中,Map 和 Set 是两种新的数据结构,它们为数据的存储和操作提供了更强大和灵活的方式。

Map:Map 是键值对的集合,其中键可以是任何类型的值(包括对象),而不仅仅是字符串。

// 创建

let myMap = new Map();

myMap.set("key1", "value1");

myMap.set(2, "value2");

myMap.set({ name: "John" }, "value3");



// 获取

console.log(myMap.get("key1"));

console.log(myMap.get(2));

console.log(myMap.get({ name: "John" }));



// 检查键是否存在

console.log(myMap.has("key1"));



// 删除键值对

myMap.delete("key1");



// 获取 Map 的大小

console.log(myMap.size);



// 遍历 Map

for (let [key, value] of myMap) {

console.log(key + ': ' value);

}
Set:Set 是一种不允许重复值的数据结构。

// 创建

let mySet = new Set();

mySet.add(1);

mySet.add(2);

mySet.add(2); // 重复添加不会有效果

mySet.add("Hello");



// 检查元素是否存在

console.log(mySet.has(1));



// 删除元素

mySet.delete(1);



// 获取 Set 的大小

console.log(mySet.size);



// 遍历 Set

for (let item of mySet) {

console.log(item);

}
symbol
在 ES6 中,Symbol 是一种新的基本数据类型,它的主要目的是创建独一无二的值,通常用于对象的属性名,以避免属性名冲突。

let sym1 = Symbol();

let sym2 = Symbol("description"); // 可以提供一个可选的描述字符串
12. 迭代器和生成器
在 ES6 中,迭代器(Iterator)和生成器(Generator)为处理数据的遍历和生成提供了更强大和灵活的方式。

迭代器(Iterator)

迭代器是一个具有 next() 方法的对象,每次调用 next() 方法都会返回一个对象,该对象包含两个属性:value (当前迭代的值)和 done (一个布尔值,表示迭代是否完成)。

// 创建一个简单的迭代器

function createIterator(arr) {

let index = 0;

return {

next() {

if (index < arr.length) {

return { value: arr[index++], done: false };

} else {

return { value: undefined, done: true };

}

},

};

}



let iterator = createIterator([1, 2, 3]);

console.log(iterator.next());

console.log(iterator.next());

console.log(iterator.next());

console.log(iterator.next());
生成器(Generator)

生成器是通过 function\* 定义的函数,可以通过 yield 表达式暂停和恢复执行,并且可以逐步生成一系列的值。

function* generateNumbers() {

yield 1;

yield 2;

yield 3;

}



let generator = generateNumbers();

console.log(generator.next());

console.log(generator.next());

console.log(generator.next());

console.log(generator.next());

posted @ 2025-03-07 10:46  小二的黑豆  阅读(19)  评论(0)    收藏  举报