ES6有何新特性?(上篇)

目录

介绍

let 和 const 

解构

模板字符串

箭头函数

Set

Map


介绍

ES 全称是ECMAScript,它是JavaScript基础构建的一种语言,JavaScript正是建立在ECMAScript语言的基础规范中建立使用的。ES6实际上是一个泛指,泛指ES2015及后续的版本。发展历程可看如下图:

20d9f6c088ab401b84651143734cf32b.jpegES6的新特性主要归为四个方面的更新:一、解决原有语法上的一些不足,二、对原有语法进行增强,三、全新的对象、全新的方法、全新的功能,四、全新的数据类型和数据结构。下面挑一些来具体讲一下吧!

let 和 const 

let关键字

let是ES6新增的用于声明变量的关键字,用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。在声明变量之前,该变量是不存在的,这时如果使用到该变量,就会抛出一个错误。

// 只在let命令所在的代码块内有效
{
    let a = 20
}
console.log(a) // ReferenceError: a is not defined

//变量b是不存在的,这时如果用到它,就会抛出一个错误
console.log(b) // 报错ReferenceError
let b = 2

使用let声明变量前,该变量都不可用,也就是大家常说的“暂时性死区”。只要块级作用域内存在let命令,这个区域就不再受外部影响。同时,let还不允许在相同作用域中重复声明。

var a = 123
if (true) {
    a = 'abc' // ReferenceError
    let a;
}

//let不允许在相同作用域中重复声明
let a = 20
let a = 30
// Uncaught SyntaxError: Identifier 'a' has already been declared

注意:若在相同的作用域,重复声明是不会报错的。在相同的作用域下重复声明才会报错!

const关键字

const声明一个只读常量,一旦声明,常量的值就不能改变。因此,const一旦声明变量,就必须立即初始化,不能留到以后赋值。如果之前用var或let声明过变量,再用const声明同样会报错。

const a = 1
a = 3
// TypeError: Assignment to constant variable.

const b;
// SyntaxError: Missing initializer in const declaration

var a = 20
let b = 20
const a = 30
const b = 30
// 都会报错

const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据,值就保存在变量指向的那个内存地址,因此等同于常量。对于复杂类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的,并不能确保改变量的结构不变。

const foo = {};

// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only

三者的区别

var、let以及const三者的区别如下:

声明方式变量提升作用域初始值重复定义
var函数级不需要允许
let块级不需要不允许
const块级必需不允许

解构

可以把解构看作是一个具有结构赋值功能的一个语法。解构主要包括两种:数组解构以及数组解构。

数组解构

单独解构:根据数组索引,将数组解构成单独的元素。若你想要获取数组中的每一个数据,数组的单独解构就会很轻松地解决该问题,不需要采取遍历获取比较麻烦的方式。同时也可以获取到自己想要的数组中某一个的元素。

const arr=[10,20,30]
const[x,y,z]=arr
console.log(x,y,z)//10 20 30
//获取某一个元素
const[,,z]=arr
console.log(z)//30

解构时可以给变量设置默认值,数组没有这个元素的话。

const arr = [10, 20, 30]

const [, , , defaultVal = '40'] = arr
console.log('设置默认值', defaultVal)//40

剩余解构:用 "...+变量名" 解构剩余参数到新数组,只能用一次。定义一个新的数组,该数组为rest,该数组会获取解构后的arr数组中的剩余参数到自己中,由于存在e,因此占了arr中的第一个数据,剩下的20,30自动到rest数组中。

const arr = [10, 20, 30]
const [e, ...rest] = arr
console.log(rest) //[20, 30]

对象解构

对象的单个或者多个解构。解构之后可以直接获取到name、age以及height对应的值。可以获取其中的某一个或者全部。

const obj = { name: 'N-A', age: 5, height: undefined }
const { name, age } = obj
console.log(name, age) // 'N-A', 5

若你不想要对象中原本的变量名,你还可以给解构出来的变量名进行重新命名。

const obj = { name: 'N-A', age: 5, height: undefined }
const { name: objName } = obj
console.log(objName)

同时与数组解构一同,也可以给解构变量设置默认值。

const obj = { name: 'N-A', age: 5, height: undefined }
const { next = 'default' } = obj
console.log(next)

模板字符串

在ES6之前,如果我们要实现字符串和一些动态的变量进行拼接时,会非常的麻烦。而ES6新增了一个模板字符串,具有换行,插值,使用标签函数进行字符串操作等功能。实现方式非常简单,就是使用反义符号``,包裹起来。

//换行
const str = `ECMA
    Script`
console.log(str)

// 插值
const strs = `random: ${Math.random()}`
console.log(strs)

模板字符串还可以用来调用函数,同时传入相应的参数。函数获取到的第一个参数为数组,该数组存放着被模板字符串拆分的字符串组合。后面的参数是接受模板字符串传入的内容。

/**
 * 字符串模板函数
 * @param {array} strs 以插值为分隔符组成的字符串数组
 * @param {string} name 插值的value,有多少个就会传入多少个
 */
const tagFunc = (strs, name, gender) => {
  const [str1, str2, str3] = strs
  const genderParsed = gender == '1' ? '男' : '女'
  // 可以在此做过滤,字符串处理,多语言等操作
  return str1 + name + str2 + str3 + genderParsed
}

// 带标签的模板字符串,
const person = {
  name: 'xiaohui',
  gender: 1,
}
// 返回值为标签函数的返回值
const result = tagFunc`my name is ${person.name}.gender is ${person.gender}`
console.log(result) //my name is xiaohui.gender is 男

箭头函数

箭头函数可以简化函数的定义,其相当于匿名函数。箭头函数就是采用箭头=>来定义函数,省去了关键字function。函数的参数在=>的前面,而函数体则在=>的后面。

当箭头函数没有参数,只有一个参数以及多个参数的情况下,其书写方式如下:

// 没有参数
let fn1=()=>{
    console.log('hello');
}
//函数有一个参数
let fn2=age=>{
    console.log(age)
}
//函数有多个参数
let fn3=(val1,val2,val3)=>{
    console.log(val1,val2,val3)
}

如果函数没有参数,则只需要写一个空括号即可,若函数有一个参数,则参数的括号可以省略。若参数有多个,则使用逗号来分隔。

若箭头函数的函数体中只有一条执行语句,则可以省去函数体中的花括号,若返回的是一个对象,则需要在函数体外再加上一个括号。若箭头函数不需要返回值,则加上void关键字。具体如下代码:

// 返回一个变量
let fn1=val=>val;
// 返回一个表达式
let fn2=(val1,val2)=>val1+val2;
//返回对象
let fn3=(name,age)=>({
    name:name,
    age:age
})
//不需要返回
let fn4=()=>void doesNotReturn();

箭头函数没有原型prototype,因此箭头函数没有this指向,它会捕获自己定义所处的外层执行环境,并继承其this值。箭头函数的this指向被定义的时候就确定了,之后不会改变。call/apply/bind也无法改变箭头函数的this指向,若想要改变,可以通过改变其继承this的外层函数的this指向来间接地改变。若箭头函数外层没有函数,则其this会指向window全局对象。(在这篇文章就不详细做演示了)

Set

Set是ES6新增的数据结构,类似于数组,但是存储的值都是不重复的,我们一般称为集合。Set本身是一个构造函数,用来生成 Set 数据结构。const s=new Set,其具有常见的方法如下。

add():添加某个值,返回 Set 结构本身。当添加实例中已经存在的元素,set不会继续添加。

delete():删除某个值,返回一个布尔值,表示删除是否成功。

has():返回一个布尔值,判断该值是否为Set的成员。

clear():清除所有成员,没有返回值。

const s = new Set();
// 增加
s.add(1).add(2).add(2); 
console.log(s)//{1,2}
//删除
s.delete(1);
console.log(s)//{2}
//判断
console.log(s.has(2))//true
//清楚
s.clear();
console.log(s)

e4568f5badc94cfc89af83df09b0f118.png

keys():Set实例的遍历方法,可以用于返回键名的遍历器。

values():返回键值的遍历器。

entries():返回键值对的遍历器。

let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

Set的主要应用,可以与扩展运算符向结合,实现数组货或者是字符串的去重。

// 数组
let arr = [3, 5, 2, 2, 5, 5];
let unique = [...new Set(arr)]; // [3, 5, 2]

// 字符串
let str = "352255";
let unique = [...new Set(str)].join(""); // "352"

Map

Map类型是键值对的有序列表,而键和值都可以是任意类型。Map是一种叫做字典的数据结构。Map本身是一个构造函数,用来生成 Map数据结构。const m = new Map()。其具有常见属性和方法如下。

size 属性:size属性返回 Map 结构的成员总数。

const map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2

set():设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。同时返回的是当前Map对象,可采用链式写法。

const m = new Map();
m.set('N-A', 6)        // 键是字符串
m.set(262, 'standard')     // 键是数值
m.set(undefined, 'nah')    // 键是 undefined
m.set(1, 'a').set(2, 'b').set(3, 'c') // 链式操作

get():get方法读取key对应的键值,如果找不到key,返回undefined。

const m = new Map();
m.set(123, 'Hello ES6!') // 键是函数
m.get(123)  // Hello ES6!

has():has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。

const m = new Map();
m.set('N-A', 6);
m.has('N-A')   // true
m.has('ABC')   // false    

delete():delete方法删除某个键,返回true。如果删除失败,返回false。

const m = new Map();
m.set('N-A', 6);
m.has('N-A')   // true
m.delete('N-A')
m.has('N-A')  // false   

clear():clear方法清除所有成员,没有返回值。

let map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
map.clear()
map.size // 0

Map同样提供了三个遍历器,keys():返回键名的遍历器。values():返回键值的遍历器。entries():返回键值对的遍历器。

const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);

for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"

for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"

for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

好啦!本文就先到这里了,由于时间关系本文写得还不够细致和深入。不足之处还请各位见谅。有什么有疑问的知识点也欢迎各位探讨学习!提前祝各位1024程序员节快乐!最近天气变冷了,各位注意保暖!

  • 115
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 190
    评论
ES6ECMAScript 2015)是JavaScript的一个重要,引入了许多新的语法和功能。以下是ES6的一些主要特性: 1. 块级作用域:引入了let和const关键字,可以在块级作用域中声明变量,解决了var关键字的作用域问题。 2. 箭头函数:使用箭头(=>)定义函数,简化了函数的写法,并且自动绑定了this。 3. 默认参数:函数参数可以设置默认值,简化了函数调用时的参数传递。 4. 模板字符串:使用反引号(`)包裹字符串,可以在字符串中插入变量和表达式,提供了更方便的字符串拼接方式。 5. 解构赋值:可以从数组或对象中提取值,并赋给变量,简化了变量的声明和赋值过程。 6. 扩展运算符:使用三个点(...)可以将数组或对象展开,方便地进行数组合并、复制和对象属性的拷贝。 7. 类和模块:引入了class关键字,可以使用面向对象的方式定义类和继承关系。同时,也支持模块化的导入和导出。 8. Promise:提供了一种更优雅的处理异步操作的方式,解决了回调地狱的问题。 9. 简化对象属性的定义:当属性名和变量名相同时,可以直接写属性名,省略冒号和赋值符号。 10. 简化迭代器和生成器:引入了for...of循环,可以更方便地遍历数组和类数组对象。同时,也支持生成器函数,可以通过yield关键字实现暂停和恢复执行。 11. 模块化的导入和导出:使用import和export关键字,可以将代码分割成多个模块,提高了代码的可维护性和复用性。
评论 190
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值