"跃迁ES6:探索JavaScript语言的最新进展(一)"

145 阅读7分钟

引言

当谈到现代前端开发中的关键技术,ES6(ECMAScript 2015)毫无疑问是一个不可或缺的话题。作为JavaScript语言的重大更新,ES6引入了许多令人振奋的新特性和语法改进,极大地改善了JavaScript编程体验并提高了代码的可读性和可维护性。本文将深入探讨ES6的新特性,从箭头函数到类和模块化,以及其他让开发者兴奋不已的特性。通过本文的阅读,您将全面了解ES6为现代JavaScript开发带来的重要改变,以及如何在您的项目中充分利用这些新特性。

let和const

1.let

  • 声明提升

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。那我们为什么要引入let呢?原来是因为var存在声明提升,我们看下面代码

//声明提升
console.log(a);
var a=1;

同学们觉得这段代码会报错吗?答案是:不会!在这段代码中,尽管在 console.log 语句之前才对a进行赋值,但由于变量声明被提升,JavaScript 实际上会将它解释为如下形式:

//声明提升
var a 
console.log(a);
a=1;

因此,即使在声明之前访问了a,也不会报错,而是会得到 undefined。

  • 暂时性死区

我们再来看下面这段代码:

let a = 1
if(true){
    console.log(a);//暂时性死区
    let a =1
}

在这段代码中,由于你在 if 语句块内使用了 let 关键字声明了一个新的变量 a,所以在这个作用域内会创建一个新的局部变量 a,并且会存在暂时性死区。暂时性死区是指在代码块内,在变量声明语句之前引用该变量,会导致 ReferenceError 错误。因此,当你尝试在 if 语句块内部访问 a 时,由于存在暂时性死区,会导致错误。

  • window
//var声明的全局变量挂载在window上而let不会
var a
console.log(window.a);
let a2
console.log(window.a2);

在浏览器的JavaScript环境中,使用var声明的全局变量会被挂载在window对象上,因此可以通过window.a来访问。但如果使用let声明全局变量,它不会被挂载在window对象上,因此无法通过window.a来访问。因此,当你运行console.log(window.a)时,如果a是用var声明的全局变量,将会在控制台输出对应的值;如果a是用let声明的全局变量,console.log(window.a)会显示undefined。

2. const

const声明一个只读的常量。一旦声明,常量的值就不能改变。这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

//报错 不能重复赋值
const a = 6
a = 7
//正确,const声明的引用类型对象的值在堆中,在栈中保存堆中的地址
const obj = {
    name : '666'
}
obj.name = '777'

解构

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构

  • 数组解构赋值
let [x, y, z] = ['a', 'b', 'c', 'd', 'e'];
console.log(x, y, z); // 输出:a b c

在这里,我们使用数组解构赋值将数组中的值分别赋给变量 x、y 和 z,多余的元素会被忽略。

  • 扩展运算符的应用
let arr = [1, 2, 3];
console.log(...arr); // 输出:1 2 3
let newArr = [0];
console.log([...newArr, ...arr]); // 输出:0 1 2 3

这里我们展示了扩展运算符在数组解构中的应用。通过使用扩展运算符,我们能够将数组中的元素“展开”,并在新数组中进行拼接操作。

  • 对象解构赋值
let {name: name1, age: age1} = {name: '浪哥', age: 19};
console.log(name1, age1); // 输出:浪哥 19

这段代码展示了如何使用对象解构赋值从对象中提取特定属性的值并赋给变量。

  • 简化语法

在对象 obj 中,使用了简化的属性值定义。这种简化的写法是 ES6 新增的特性,当属性名和变量名相同时,可以直接写属性名,JavaScript 会自动将变量的值赋给该属性。因此,age 变量的值被赋给了对象 obj 中同名的属性。

var age = 18; 
let obj = { name: '655', age//age:age };
console.log(obj.age); // 输出:18

字符串

这里我们将介绍一些字符串新增的一些方法

  • 字符串索引和 at() 方法
let str = 'abcdefg';
console.log(str[2]); // 输出:c
console.log(str.at(2)); // 输出:c

字符串可以像数组一样使用索引来访问特定位置的字符,也可以使用 at() 方法来获取指定位置的字符。

  • padStart() 和 padEnd() 方法
let str2 = '19979659226';
console.log(str2.padStart(20, '0')); // 输出:00000000019979659226

padStart(length, padString) 方法可以在字符串前面填充指定的字符,使字符串达到指定的长度。如果原始字符串的长度大于或等于指定的长度,则返回原始字符串。

  • JSON 对象的 stringify() 和 parse() 方法
let obj = {
    a: 1,
    b: 2
};
console.log(obj); // 输出:{ a: 1, b: 2 }
let str3 = JSON.stringify(obj); // 对象转换为字符串
console.log(str3); // 输出:{"a":1,"b":2}
console.log(JSON.parse(str3)); // 字符串转换为对象

使用 JSON.stringify() 方法可以将 JavaScript 对象转换为 JSON 字符串,而 JSON.parse() 方法可以将 JSON 字符串解析为 JavaScript 对象。

Set和Map

1.Set

  • 是一种key和value相等的特殊对象并且set对象中的值是唯一的

set是是一种key和value相等的特殊对象,所以我对于set的理解就是,既然key和value相等,而对象的key是不能重复的,所以set存在一个特性:set对象中的值是唯一的

let arr = [1,1,2,3,3]
function unique(arr){
    // let s = new Set()
    // let res = Array.from(s)
    // return res
    return[...new Set(arr)]
}
console.log(unique(arr));//1,2,3
  • 具有迭代器
let set = new Set([1,2,3,4]) //类数组
for(let item of set){ 
    console.log(item); //1 2 3 4
} 
for(let item of set.entries()){ 
    console.log(item); //返回键值对 [1, 1] [2, 2] [3, 3] [4, 4]
} 
let s = '1216652;' 
for(let item of s){
    console.log(item); //1 2 1 6 6 5 2 ;
}

2.Map

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

let map = new Map()
//如果需要放入初始值
//let map  = new Map([['name','老王']]);
//console.log(map);
let obj ={a:1}
map.set(obj,'hello')
console.log(map.get(obj));
map.forEach((value,key,map)=>{
    console.log(value,key,map);
 })

在这段代码中,首先创建了一个新的 Map 对象 map,然后创建了一个对象 obj,并将其作为键,值为 'hello' 存入了 Map 中。接着使用 get 方法获取了 obj 对应的值,并打印输出。

随后使用 forEach 方法遍历了 Map 中的元素,对于每个元素,都会执行指定的回调函数。需要指出的是,在 forEach 方法中的回调函数的参数分别为元素的值、键、以及所遍历的 Map 对象本身。

在你的代码中,obj 是作为 Map 的键来使用的,因此在 forEach 方法中,回调函数的参数 value 代表键的值,key 代表键本身,map 代表当前的 Map 对象。

对于 map.get(obj) 的输出应该是 'hello',表示成功地从 Map 中取出了 obj 对应的值。

WeakSet 和 WeakMap

WeakSet和WeakMap 与set和map的主要方法大致相同,这里我们拿WeakSet来说

一个对象被WeakSet所引用,在垃圾回收机制的眼中该对象是没有被引用的 那么只要垃圾回收机制一生效,该对象所占据的内存空间就会被销毁

let obj = {
    name:'德玛西亚'
}
let ws = new WeakSet()//只能存Symbol和对象
ws.add(obj)
// obj = null
console.log(ws);//{}空对象

我们先看这段代码的运行结果

image.png 我们可以看到,obj不见了,因为WeakSet是弱引用,被垃圾回收机制忽略了对于obj的引用,所以在let 了obj以后,obj就被回收了

结尾

以上是关于ES6新特性的简要介绍,我们只涵盖了部分内容。接下来,我们将持续更新其他的ES6新特性,敬请关注我们的后续文章,一起探索现代 JavaScript 的魅力!