JavaScript系列 — ES6、ES7、ES8 新特性

原文地址:ES6、ES7、ES8特性一锅炖(ES6、ES7、ES8学习指南) 这里作学习笔记

ES6 新特性

  • let 与 const
  • 箭头函数
  • 模块化
  • 模板字符串
  • 解构赋值
  • 延展操作符
  • Promise
  • 函数参数默认值
  • 对象属性简写

1. let 与 const

在之前JS是没有块级作用域的,const与let填补了这方便的空白,const与let都是块级作用域

使用 var 定义的变量为函数级作用域:

{
  var a = 10;
}

console.log(a); // 输出10
复制代码

使用 let 与 const 定义的变量为块级作用域:

{
  let a = 10;
}

console.log(a); //-1 or Error“ReferenceError: a is not defined”
复制代码

2. 箭头函数

详见 JavaScript系列 — 普通函数、箭头函数、构造函数的区别及其对应 this 指向

3. 类(class)

对熟悉Java,object-c,c#等纯面向对象语言的开发者来说,都会对class有一种特殊的情怀。ES6 引入了class(类),让JavaScript的面向对象编程变得更加简单和易于理解

class Animal {
    // 构造函数,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数.
    constructor(name,color) {
      this.name = name;
      this.color = color;
    }
    // toString 是原型对象上的属性
    toString() {
      console.log('name:' + this.name + ',color:' + this.color);

    }
  }

 var animal = new Animal('dog','white');//实例化Animal
 animal.toString();

 console.log(animal.hasOwnProperty('name')); //true
 console.log(animal.hasOwnProperty('toString')); // false
 console.log(animal.__proto__.hasOwnProperty('toString')); // true

 class Cat extends Animal {
  constructor(action) {
    // 子类必须要在constructor中指定super 函数,否则在新建实例的时候会报错.
    // 如果没有置顶consructor,默认带super函数的constructor将会被添加、
    super('cat','white');
    this.action = action;
  }
  toString() {
    console.log(super.toString());
  }
 }

 var cat = new Cat('catch')
 cat.toString();

 // 实例cat 是 Cat 和 Animal 的实例,和Es5完全一致。
 console.log(cat instanceof Cat); // true
 console.log(cat instanceof Animal); // true
复制代码

4. 模块化

ES5不支持原生的模块化,在ES6中模块作为重要的组成部分被添加进来。模块的功能主要由 export 和 import 组成。每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过import来引用其它模块提供的接口。同时还为模块创造了命名空间,防止函数的命名冲突。

导出(export)

ES6允许在一个模块中使用export来导出多个变量或函数。

导出变量

//test.js
export var name = 'Rainbow'
复制代码

ES6不仅支持变量的导出,也支持常量的导出。 export const sqrt = Math.sqrt; // 导出常量

ES6将一个文件视为一个模块,上面的模块通过 export 向外输出了一个变量。一个模块也可以同时往外面输出多个变量。

 //test.js
 var name = 'Rainbow';
 var age = '24';
 export {name, age};
复制代码

导出函数

// myModule.js
export function myModule(someArg) {
  return someArg;
}
复制代码

导入(import)

定义好模块的输出以后就可以在另外一个模块通过import引用。

import {myModule} from 'myModule'; // main.js
import {name,age} from 'test'; // test.js
复制代码

一条import 语句可以同时导入默认函数和其它变量。import defaultMethod, { otherMethod } from 'xxx.js';

5. 模板字符串

ES6支持模板字符串,使得字符串的拼接更加的简洁、直观

  • 不使用模板字符串
var name = 'Your name is ' + first + ' ' + last + '.'
复制代码
  • 使用模板字符串
var name = `Your name is ${first} ${last}.`
复制代码

6. 解构赋值

解构赋值语法是JavaScript的一种表达式,可以方便的从数组或者对象中快速提取值赋给定义的变量

获取数组中的值

  • 从数组中获取值并赋值到变量中,变量的顺序与数组中对象顺序对应
var foo = ["one", "two", "three", "four"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

//如果你要忽略某些值,你可以按照下面的写法获取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

//你也可以这样写
var a, b; //先声明变量

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
复制代码
  • 为变量设置一个默认值
var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
复制代码
  • 方便交换变量的值
var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
复制代码

获取对象中的值

const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};

const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"
复制代码

7. 延展操作符(…)

延展操作符...可以在函数调用/数组构造时, 将数组表达式或者 string 在语法层面展开;还可以在构造对象时, 将对象表达式按 key-value 的方式展开

语法

  • 函数调用
myFunction(...iterableObj);
复制代码
  • 数组构造或字符串
[...iterableObj, '4', ...'hello', 6];
复制代码
  • 构造对象时,进行克隆或者属性拷贝
let objClone = { ...obj };
复制代码

应用场景

  • 在函数调用时使用延展操作符(最常用:函数外不用一个一个传,直接整体传,函数内会将其一个一个拆开)
function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1, 2, 3];

//不使用延展操作符
console.log(sum.apply(null, numbers));

//使用延展操作符
console.log(sum(...numbers));  // 6
复制代码
  • 构造数组

没有展开语法的时候,只能组合使用 push,splice,concat 等方法,来将已有数组元素变成新数组的一部分。有了展开语法, 构造新数组会变得更简单、更优雅:

const stuendts = ['Jine','Tom']; 
const persons = ['Tony',... stuendts,'Aaron','Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]
复制代码
  • 数组拷贝
var arr = [1, 2, 3];
var arr2 = [...arr]; // 等同于 arr.slice()
arr2.push(4); 
console.log(arr2)//[1, 2, 3, 4]
复制代码
  • 连接多个数组
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 将 arr2 中所有元素附加到 arr1 后面并返回
//等同于
var arr4 = arr1.concat(arr2);
复制代码

8. Promise

详细见 JavaScript系列 — Promise、Generator、async及await

9. 对象属性简写

在ES6中允许我们在设置一个对象的属性的时候不指定属性名

  • 不使用 ES6
const name='Ming',age='18',city='Shanghai';
        
const student = {
    name:name,
    age:age,
    city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
复制代码
  • 使用 ES6
const name='Ming',age='18',city='Shanghai';
        
const student = {
    name,
    age,
    city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
复制代码

10. 函数参数默认值

ES6支持在定义函数的时候为其设置默认值:

function foo(height = 50, color = 'red')
{
    // ...
}
复制代码
  • 不使用 ES6 设置默认值:
function foo(height, color)
{
    var height = height || 50;
    var color = color || 'red';
    //...
}
复制代码

这样写一般没问题,但当参数的布尔值为false时,就会有问题了。比如,我们这样调用foo函数:

foo(0, "")
复制代码

因为 0 的布尔值为 false,这样 height 的取值将是 50。同理 color 的取值为 red

所以说,函数参数默认值不仅能是代码变得更加简洁而且能规避一些问题。

ES7 新特性

  • 数组的 includes() 方法
  • 指数操作符

1. Array.prototype.includes()

includes() 函数用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回false。

includes 函数与 indexOf 函数很相似,下面两个表达式是等价的:

arr.includes(x)
arr.indexOf(x) >= 0
复制代码

接下来我们来判断数字中是否包含某个元素:

  • ES7 之前的做法

使用indexOf()验证数组中是否存在某个元素,这时需要根据返回值是否为-1来判断:

let arr = ['react', 'angular', 'vue'];

if (arr.indexOf('react') !== -1)
{
    console.log('react存在');
}
复制代码
  • 使用 ES7 的 includes() 方法
let arr = ['react', 'angular', 'vue'];

if (arr.includes('react'))
{
    console.log('react存在');
}
// 使用includes()验证数组中是否存在某个元素,这样更加直观简单
复制代码

2. 指数操作符(2**5 === 32)

在ES7中引入了指数运算符****具有与Math.pow(..)等效的计算结果

  • 不使用指数操作符
// 使用自定义的递归函数calculateExponent或者Math.pow()进行指数运算
function calculateExponent(base, exponent)
{
    if (exponent === 1)
    {
        return base;
    }
    else
    {
        return base * calculateExponent(base, exponent - 1);
    }
}

console.log(calculateExponent(2, 10)); // 输出1024
console.log(Math.pow(2, 10)); // 输出1024
复制代码
  • 使用指数操作符

使用指数运算符**,就像+、-等操作符一样:

console.log(2**10);// 输出1024
复制代码

ES8 新特性

  • async/await
  • Object.values()
  • Object.entries()
  • Object.getOwnPropertyDescriptors()
  • padStart、padEnd
  • 函数参数列表结尾允许逗号

1. async/await

详细见 JavaScript系列 — Promise、Generator、async及await

2. Object.values()

Object.values()是一个与Object.keys()类似的新函数,但返回的是Object自身属性的所有值,不包括继承的值。

假设我们要遍历如下对象obj的所有值:

const obj = {a: 1, b: 2, c: 3};
复制代码
  • 不使用Object.values() : ES7
const vals=Object.keys(obj).map(key=>obj[key]);
console.log(vals);//[1, 2, 3]
复制代码
  • 使用Object.values() : ES8
const values=Object.values(obj1);
console.log(values);//[1, 2, 3]
复制代码

从上述代码中可以看出Object.values()为我们省去了遍历key,并根据这些key获取value的步骤

3. Object.entries

Object.entries()函数返回一个给定对象自身可枚举属性的键值对的数组。

接下来我们来遍历上文中的obj对象的所有属性的key和value:

  • 不使用Object.entries() :ES7
Object.keys(obj).forEach(key=>{
	console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3
复制代码
  • 使用Object.entries() :ES8
for(let [key,value] of Object.entries(obj1)){
	console.log(`key: ${key} value:${value}`)
}
//key:a value:1
//key:b value:2
//key:c value:3
复制代码

3. Object.getOwnPropertyDescriptors()

返回obj对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象

const obj2 = {
	name: 'Jine',
	get age() { return '18' }
};
Object.getOwnPropertyDescriptors(obj2)
复制代码

image.png

4. padStart、padEnd

str.padStart(targetLength,[padString])

  • targetLength:当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
  • padString:(可选)填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断,此参数的缺省值为 ” “
console.log('0.0'.padStart(4,'10')) // 10.0
console.log('0.0'.padStart(20))     //                0.00    
复制代码

str.padEnd(targetLength,[padString])

  • targetLength:当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
  • padString:(可选) 填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断,此参数的缺省值为 ” “
console.log('0.0'.padEnd(4,'0'))  // 0.00    
console.log('0.0'.padEnd(10,'0')) // 0.00000000
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享