ES6新语法(前端必备)

(一)模板字符串

  1. 使用方法:将字符串写在 ` ` 里->> 就是键盘上tab键上面那个键
  2. 允许多行并保留编辑格式(缩进和换行会予以保留)
  3. 支持内嵌表达式:语法:${表达式}
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

(二)浏览器加载

defer与async的区别是:

defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;

async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。

一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>

(三)解构赋值 ->>分为数组解构赋值和对象解构赋值

对右侧的数据进行解构(解析解构),把值对应的一一赋值给左侧的变量。

1-数组解构赋值

01-左侧是 [] ,值是一一(位置)对应的。
02-如果解构不成功,则变量的值为undefined
03-等号的右边的数据具有Iterator接口,都可以采用数组形式解构赋值;

04-解构赋值允许指定默认值,ES6中使用严格相等符(===),判断一个位置是否有值,如果一个数组的成员不严格等于undefined,默认值不会生效。默认值可以引用解构赋值的其他已被声明的变量。

//通常情况下
var first = someArray[0];
var second = someArray[1];
var third = someArray[2];

//解构赋值
let [first, second, third] = someArray; //比上面简洁多了吧

//还有下面例子
let [,,third] = [1,2,3];
console.log(third); //3

let [first,...last] = [1,2,3];
console.log(last); //[2,3]

2-对象解构赋值

01-左侧是{},key一一对应。左侧变量的名称和右侧对象中属性的名称是有关联的(必须名称相同)

02-与数组解构赋值一样,也可以指定默认值

03-如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错

//对象解构
let {name,age} = {name: "lisi", age: "20"};
console.log(name); //lisi
console.log(age); //20

//注意
let {ept1} = {};
console.log(ept1); //undefined
let {ept2} = {undefined};
console.log(ept2); //undefined
let {ept3} = {null};
console.log(ept3); //null

or

    // 对象解构赋值
    var cat = {name:'kitty', leg:4}
    // 把对象中的成员当做变量解析出来
    var {name, leg} = cat

(四)let

 01-声明变量,类似 var,但是相比较var,还是有很大的不同。

02-不允许重复声明
         var如果重复声明,则后面的声明会覆盖前面的声明。而运行到let的重复声明时,浏览器会报错,提示说该变量已经被声明。 
03-必须先声明后使用(暂存死区)->> 在代码块内,在let声明变量之前,该变量都是不可用的。在语法上,称为“暂时性死区”。

04-var具有变量提升的效果,即如果在声明之前使用,该变量的值为undefined,而let必须声明再使用,否则会报错。

05-支持块级作用域:一对 {} 产生一个块,在 {} 内部就会形成一个独立的作用域:块作用域。

比如:下面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局都只有一个变量i。每一次循环,变量i的值都发生改变。而循环内的i都指向全局的i,导致运行时输出的最后一轮的i的值,也就是5个5。

     for (var i=0; i<5; i++) {

          setTimeout(function() {
              console.log(i);
          }, 1000);

      }

再比如:下面:变量i是let声明的,当前的i只在本轮循环内有效,所以每一次循环的i其实都是一个新的变量。

      for (let i = 0; i<5; i++) {

          setTimeout(function() {
              console.log(i);
          }, 1000);

      }

  另外,for循环还有一个特别之处,就是设置循环变量那部分是一个父作用域,而循环体内部的一个单独的子作用域。上面代码正确运行,输出5次,分别为1,2,3,4,5。
(五)const

常量声明

  • 支持块作用域
  • 先声明后使用
  • 不允许重复声明
  • 常量声明一定需要初始化-声明之后立马赋值
const a = 1

说白了,现在a的初始值就是1, 你无法改变,所以给我的感觉就是,只要我在某一个页面上看见了const。我就觉得特别安全。哈哈哈。因为a就等于1 不可能在等于其他的了。 除非有杠精。 

(六)数字扩展

01-)2进制:0b/0B 开头 Binary【es6新增】
02-)8进制:0o/0O 开头 Octal【es6新增】
03-)10进制:1-9的数字开头 Decimal
04-)16进制:0x/0X 开头 Hexadecimal
05-)Number.isFinite() 用来判断一个数字是否是有限的
06-)Number.isInteger() 用来判断一个数字是否是整数,注意3.0和3的判断结果都为整数

(七)对象冻结

01-)如果想要冻结对象,应该使用object.freeze方法。但是有局限性:该方法只能冻结对象内的第一层属性,也就是说如果要冻结的对象有属性值为对象,那这个作为属性值的对象是无法进行冻结的。 
02-)要想达到深度冻结,则需要运用递归将对象的属性也进行冻结。

 var deepFreeze = (obj) =>{
     Object.freeze(obj);
     Object.keys(obj).forEach((key,i) =>{
         if(typeof obj[key] === 'object'){
             deepFreeze(obj[key]);
         }
     })
 }

(八)数组扩展

1-Array.from()

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map) ->> set和Map还不是很明白,后面会讲到。

2-...运算符 ->>我觉得这个特别好玩。哈哈。 接下来可以看一波Sao操作

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
  • 关于函数传参的问题,如果函数直接用...传参,传入的参数实际上是个数组,且后面不能再有参数。如果函数参数定义了一个数组,用...传入,实际上参数为数组中的值
function fn(...items){}
//等同于
function fn([数组内容]){}

let items = ['a', 'b', 'c']
function fn(...items){}
// 等同于
function fn('a', 'b', 'c') {}

3-...运算符的应用

  • 复制数组(克隆数组)
let arr1 = [1, 2, 3]
let arr2 = [...arr1] // [1, 2, 3]
  • 合并数组
const arr1 = ['a', 'b']
const arr2 = ['c']
const arr3 = ['d', 'e']
const arr4 = [...arr1, ...arr2, ...arr3] // [ 'a', 'b', 'c', 'd', 'e' ]
  • 与解构赋值结合
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]
  • 将字符串转换为真正的数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]

4-Array.of(), 用于将一组值,转换为数组。

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

5-数组实例的fill()

  • 三个参数,后面两个可以省略,第一个参数为替换成什么内容,第二个为替换的起始位置,第三个为替换的终止位置
['a', 'b', 'c'].fill(7)
// [7, 7, 7]

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

6-数组实例的 entries(),keys() 和 values()

三个方法都是遍历数组,都可以用for...of...

唯一的区别是:

keys()是对键名的遍历、

values()是对键值的遍历,

entries()是对键值对的遍历。

所以用什么不用我来过多说明了吧。

直接上代码:

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"

(九)Set和Map结构

1-Set

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成Set数据结构。此结构不会添加重复的值(你想到了什么,一定想到了数组去重)

// 例一
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

// 例二
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5

// 例三 数组去重
[...new Set(array)]

2-Map

这个结构我个人感觉不如对象好用,没用过。实际上Map结构就是键值对的结构,里面设置和获取分别用set和get方法,我要设置的话每次都set一下,我觉得很不方便。 

总结: 我觉得还是直接使用Set还是比较好一点呢。 ->> 各位大侠怎么看。

----我好像忘记了更新一个 Promise、async和await

太晚了, 我先睡觉了。---现在已经是凌晨01.17了。--

明天等着CSDN团队审核就把这篇文章给置顶起来。

猜你喜欢

转载自blog.csdn.net/weixin_43595461/article/details/90554534