ES6基础详解

ES6理解

当问到ES6时,通常指的是JavaScript的ECMAScript 2015标准。以下是关于ES6的一些常见内容和特性:

  1. let 和 const:let 和 const 是用于声明变量的关键字。使用 let 声明的变量是块级作用域的,而使用 const 声明的变量则是常量,它们的值不能被重新赋值。
  2. 箭头函数:箭头函数是一种更简洁的函数定义方式,它使用箭头 => 来代替 function 关键字,并且不需要写 return 关键字来返回值。
  3. 模板字符串:模板字符串允许在字符串中插入变量和表达式,使用反引号 ` 和 ${} 来实现,可以使字符串的拼接更加方便和易读。
  4. 解构赋值:解构赋值是一种从数组或对象中提取数据并将其赋值给变量的语法,可以使代码更加简洁。
  5. 类和继承:ES6引入了类和继承的概念,使得JavaScript更加像面向对象的编程语言,同时也更加易于维护和扩展。
  6. Promise:Promise 是一种处理异步操作的方法,可以避免回调地狱的问题,使代码更加易于编写和理解。
  7. 模块化:ES6引入了模块化的概念,使得JavaScript代码可以被拆分成独立的模块,使得代码更加易于维护和重用。

1. let和const

当被问到let和const时,我可以从以下几个方面来回答:

  • 定义:let和const是ES6引入的两种声明变量的方式。其中let声明的变量是可修改的,而const声明一个只读的常量。一旦声明,常量的值就不能改变。
  • 作用域:let和const都是块级作用域,只在声明的块内部有效。在块外部无法访问到声明的变量。
  • 变量提升:使用let声明的变量不会被变量提升,需要在声明之后才能使用;而使用const声明的变量也不会被变量提升,但在声明之前使用会报错。
  • 最佳实践:建议在需要修改变量值时使用let,而在值不需要改变时使用const。
let count = 0; // 声明一个可修改的变量
count++; // 可以修改变量的值
console.log(count); // 输出 1

const PI = 3.14159; // 声明一个常量
// PI++; // 不能修改常量的值,会报错
console.log(PI); // 输出 3.14159

// let和const都是块级作用域
if (true) {
  let innerVar = 'inner variable';
  const INNER_CONST = 'inner constant';
}
// console.log(innerVar); // 无法访问到let声明的变量,会报错
// console.log(INNER_CONST); // 无法访问到const声明的常量,会报错

使用const声明的变量被称为常量,意味着它们的值不能被重新赋值。一旦使用const声明一个变量并初始化它的值,就不能再改变这个值了。

需要注意的是,虽然使用const声明的变量被称为常量,但这并不意味着它们的值是不可变的。如果使用const声明一个对象或数组,可以修改它们的属性或元素,因为它们的引用没有改变。

const PI = 3.14159; // 声明一个常量
// PI = 3; // 不能修改常量的值,会报错

const arr = [1, 2, 3]; // 声明一个常量数组
arr.push(4); // 可以修改常量数组的元素
console.log(arr); // 输出 [1, 2, 3, 4]

const obj = { name: 'John', age: 30 }; // 声明一个常量对象
obj.age = 31; // 可以修改常量对象的属性
console.log(obj); // 输出 { name: 'John', age: 31 }

需要注意的是,在使用const声明对象或数组时,虽然可以修改它们的属性或元素,但不能重新赋值给它们一个新的对象或数组,因为这会改变它们的引用,从而违反了const声明的不可重新赋值的规则。

2. 解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
在ES6之前,从数组或对象中提取数据的方法是使用索引或属性名来访问它们的元素或属性。但是,如果需要提取的数据很多,这样做会显得非常繁琐。
使用解构赋值可以使代码更简洁、更易读。解构赋值的语法是在赋值语句的左边使用一个模式,模式用于指定要提取的数据的结构,然后将右侧的数组或对象解构为变量,这些变量与模式匹配并进行赋值。

  • 从数组中解构:
// 从数组中解构赋值
const [a, b, c] = [1, 2, 3];
console.log(a); // 输出 1
console.log(b); // 输出 2
console.log(c); // 输出 3

  • 从对象中解构:
// 从对象中解构赋值
const { name, age } = { name: 'John', age: 30 };
console.log(name); // 输出 'John'
console.log(age); // 输出 30

  • 从嵌套的对象或数组中解构:
// 从嵌套的对象或数组中解构赋值
const { name, address: { city } } = { name: 'John', address: { city: 'New York' } };
console.log(name); // 输出 'John'
console.log(city); // 输出 'New York'

const [a, [b, c]] = [1, [2, 3]];
console.log(a); // 输出 1
console.log(b); // 输出 2
console.log(c); // 输出 3

需要注意的是,解构赋值是基于位置和名称进行匹配的,因此如果在使用对象解构时要使用属性名作为变量名,必须与对象中的属性名匹配。另外,可以在解构赋值语法中使用默认值来处理未定义的值或值为undefined的情况。

3.promise

  • Promise 是什么?Promise 是 JavaScript 中的一种异步编程解决方案,可以更加优雅和简洁地处理回调地狱和多层嵌套的问题。
  • Promise 的基本用法是什么?Promise 可以通过 new Promise() 构造函数来创建一个 Promise 实例。Promise 实例可以通过 .then()、.catch()、.finally() 等方法来处理异步操作的成功、失败和结束,从而实现对异步操作的管理和控制。
  • Promise 的特点是什么?Promise 有以下几个特点:Promise 对象的状态不受外界影响,一旦状态改变就不会再变;Promise 一旦被创建就会立即执行;Promise 可以链式调用,即一个 .then() 可以接一个 .then();Promise 可以通过 .catch() 捕获异常;Promise 可以通过 .finally() 无论成功失败都会执行最终操作。
  • Promise 的优缺点是什么?Promise 的优点是:更加优雅和简洁地处理异步操作,避免了回调地狱和多层嵌套的问题;可以更加清晰和明确地表示异步操作的成功和失败。Promise 的缺点是:对于初学者来说,可能需要一定的学习成本;在处理复杂异步操作时,可能需要多层 Promise 嵌套,导致代码可读性降低。
  • 除了用于处理异步操作,Promise还可以用于解决回调地狱问题和实现并发控制。

回调地狱是指由于多次嵌套回调函数而导致代码难以阅读和维护的问题。使用Promise可以避免回调地狱问题,因为Promise提供了链式调用的方式,将多个异步操作串联在一起,使代码结构更加清晰和易读。

并发控制是指在某些场景下需要同时执行多个异步操作,并且需要等待所有异步操作完成后再进行下一步处理。使用Promise.all方法可以实现并发控制,将多个Promise实例包装成一个Promise实例,等待所有Promise实例都完成后返回结果,这样可以提高异步操作的效率。同时,也可以使用Promise.race方法实现对多个Promise实例的竞争,只要有一个Promise实例先完成了,就立即返回其结果。

4.async和await

  • async 和 await 是什么?async 和 await 是 JavaScript 中的异步编程解决方案,是 Promise 的语法糖,用于更加优雅和简洁地处理异步操作。
  • async 和 await 的基本用法是什么?async 用于声明一个异步函数,该函数内部可以使用 await 等待一个 Promise 对象的返回值。await 会暂停异步函数的执行,直到 Promise 对象的状态发生变化(变为 resolved 或 rejected),然后返回 Promise 对象的结果。
  • async 和 await 的优点是什么?async 和 await 使异步代码更加清晰和简洁,避免了回调地狱和多层嵌套的问题;使用 async 和 await 可以更加直观地表示异步操作的执行顺序,便于代码的维护和阅读。

5.Set和Map

Set
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 可以用来去重、过滤等,常用方法有 add、delete、has、clear、size 等。

  • 在实现上,Set 内部使用了哈希表来存储成员值,因此添加和查询操作的时间复杂度都是 O(1),效率比数组高。
  • 在实际应用中,Set 可以用来去重数组、统计词频、过滤数据等。同时,Set 也有其局限性,如无法通过索引访问成员、不能直接修改成员等。在使用时需要根据具体的场景和需求进行选择。

Set本身是一个构造函数,用来生成 Set 数据结构。

const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
  console.log(i);
}
// 2 3 5 4

**WeakSet **
WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。

  • WeakSet 的成员只能是对象,而不能是其他类型的值。

  • 其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
    Map
    在 ES6 中,Map 是一种用于存储键值对的数据结构,其中每个键可以是任何类型,而值可以是任何类型或者对象。与 JavaScript 的对象不同,Map 对象可以保留插入的顺序,并且键和值的类型可以不同。常用的方法有 set(key, value)、get(key)、has(key)、delete(key)、clear() 等。Map 对象提供了一些实用的功能,例如可以通过 size 属性获取 Map 中元素的数量,也可以使用 forEach 方法对 Map 中的每个元素执行相应的操作。
    在实际的开发中,Map 主要用于存储键值对,并且提供了快速查找、添加、删除、遍历等操作,具体应用如下:

  • 存储缓存数据:Map 可以用于存储缓存数据,可以根据键快速查找相应的值,避免重复计算和网络请求。

  • 存储数据结构:Map 可以用于存储有序的数据结构,例如有序列表或排序集合等,可以根据键值对进行排序或查找。

  • 替代对象或数组:Map 可以代替对象或数组,提供更灵活的操作,可以存储任何类型的键值对,而不仅限于字符串。

  • 数据处理和转换:Map 可以用于对数据进行处理和转换,例如对数组进行去重、排序和映射等操作,可以大大简化代码逻辑。
    weakMap
    WeakMap结构与Map结构类似,也是用于生成键值对的集合。

6.箭头函数

箭头函数是ES6新增的一种函数定义语法,相较于传统的函数定义语法,他有以下几个特点:

  • 箭头函数使用 "=>"符号来定义函数
  • 如果函数只有一个参数,可以省略括号,如果没有参数,必须使用空括号。
  • 如果函数体只有一条语句,可以省略花括号和 return 关键字;否则必须使用花括号和 return 关键字。
  • 箭头函数没有自己的 ‘this’,他的‘this’继承自外层作用域的‘this’
// 定义一个无参箭头函数
const sayHello = () => {
  console.log('Hello!');
}

// 定义一个有参箭头函数
const add = (x, y) => {
  return x + y;
}

// 简写的有参箭头函数
const multiply = (x, y) => x * y;

// 带有 this 的箭头函数
const person = {
  name: 'John',
  age: 30,
  sayHi: function() {
    setTimeout(() => {
      console.log(`Hi, my name is ${this.name}.`);
    }, 1000);
  }
};

7.函数的扩展

函数参数的默认值
ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

function log(x, y = 'World') {
  console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

rest 参数
ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {![在这里插入图片描述](https://img-blog.csdnimg.cn/55e8219b4c6c486e95fb549705ab2e99.png#pic_center)

  let sum = 0;
  for (var val of values) {
    sum += val;
  }
  return sum;
}
add(2, 5, 3) // 10

这里我有点记不清arguments所以我在这里会提一下

1.arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度,在调用函数时,我们所传递的实参都会在arguments中保存,arguments . length可以用来获取实参的长度
2.我们即使不定义形参,也可以通过arguments来使用实参,arguments [0]表示第一个实参arguments [1]表示第二个实参
3.它里边有一个属性叫做callee这个属性对应一个函数对象,就是当前正在指向的函数的对象

在这里插入图片描述
下面是一个 rest 参数代替arguments变量的例子。

// arguments变量的写法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}
// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();

arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用Array.prototype.slice.call先将其转为数组。rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。

8.扩展运算符

数组的扩展运算符是ES6新增的语法,用于将一个数组转为用逗号分隔的参数序列,以便在函数调用时方便地传递参数。
例如,假设有一个数组 arr,我们可以使用扩展运算符将其转换为参数序列并将其传递给一个函数:

const arr = [1, 2, 3];
myFunction(...arr);

在上述代码中,myFunction() 是一个函数,我们使用扩展运算符将数组 arr 转换为参数序列并将其传递给该函数。当函数调用时,每个数组元素都被作为单独的参数传递给函数。
扩展运算符还可以用于将一个数组合并到另一个数组中。例如,假设有两个数组 arr1 和 arr2,我们可以使用扩展运算符将它们合并为一个新的数组 arr3:

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [...arr1, ...arr2];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桔梗人柱力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值