ES6
ES7
ES8
- async/await
- Object.values()
- Object.entries
- String padding
- 函数参数列表结尾允许逗号
- Object.getOwnPropertyDescriptors()
类
对熟悉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();
继承
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();
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
class的本质,由下可以发现class的本质还是一个函数,class的相关语法及继承,也是原型链的语法糖表现形式。
console.log(type of Animal) // function
console.log(Animal) //可以发现在Animal中定义的constructor和toString都在Animal的prototype中
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
模块化
导出export 与 导入import
导出导入变量常量
export var name = 'Rainbow'
export const sqrt = Math.sqrt
import {name} from "./test.js"
import {sqrt} from "./test.js"
导出导入多个变量
var name = 'Rainbow';
var age = '24';
export {name, age};
import {name, age} from "./test.js"
导出导入函数
export function myfn(someArg) {
return someArg;
}
import {myfn} from "./test.js"
myfn("arg")
导出重命名
export {
myName as name,
myAge as age,
myfn as fn
}
import {name, age, fn} from "./test.js"
导入重命名
import { myName as name, myAge as age} from "./test.js"
直接导入整个模块
import * as info from "./test.js";//通过*来批量接收,as 来指定接收的名字
console.log(info.myfn());
console.log(info.myAge);
console.log(info.myName);
默认导出
//一个模块只能有一个默认导出,对于默认导出,导入的名称可以和导出的名称不一致
export default function() {
return "默认导出一个方法"
}
import myFn from "./test.js";//注意这里默认导出不需要用{}。
console.log(myFn());//默认导出一个方法
//可以将所有需要导出的变量放入一个对象中,然后通过export default进行导出
export default {
myFn() {
return "默认导出一个方法"
},
myName:"laowang"
}
import myObj from "./test.js";
console.log(myObj.myFn(), myObj.myName);//默认导出一个方法 laowang
//同样也支持混合导出
export default function() {
return "默认导出一个方法"
}
export var myName="laowang";
import myFn, {myName} from "./test.js";
console.log(myFn(),myName);//默认导出一个方法 laowang
箭头函数
箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体;
三个特点
- 不需要
function关键字来创建函数 - 箭头之后可以直接是一个表达式,或者是大括号括起的函数体
- 继承当前上下文的
this关键字
函数参数默认值
ES6支持在定义函数的时候为其设置默认值// ES6;
function foo(height = 50, color = 'red') {
console.log("height:" + height + ", color:" + color);
}
foo(30, 'blue'); // height:30, color:blue
foo();// height:50, color:red
ES6之前,当未传入参数时
function foo(height, color) {
var height = height || 50;
var color = color || 'red';
console.log("height:" + height + ", color:" + color);
}
这样写一般没问题,但当参数的布尔值为false时,就会有问题了。比如,我们这样调用foo函数:
foo(0, "")
因为0的布尔值为false,这样height的取值将是50。同理color的取值为red
所以说,函数参数默认值不仅能是代码变得更加简洁而且能规避一些问题。
模板字符串
ES6支持模板字符串,使得字符串的拼接更加的简洁、直观。
在ES6中通过${}就可以完成字符串的拼接,只需要将变量放在大括号之中。
不使用模板字符串:
var name = 'Your name is ' + first + ' ' + last + '.'
使用模板字符串:
var name = `Your name is ${first} ${last}.`
解构赋值
解构赋值语法是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" 延展操作符
Spread/Rest操作符
Spread/Rest...可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开或者将传入参数合并;还可以在构造对象时, 将对象表达式按key-value的方式展开。
函数调用时使用Spread操作符
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
//使用延展操作符
console.log(sum(...numbers)); // 6
函数传参时使用Rest操作符
function foo(...args) {
console.log(args);
}
foo( 1, 2, 3, 4, 5);
数组、对象拷贝
var arr = [1, 2, 3];
var arr2 = [...arr];
var obj1 = { foo: 'bar', x: 42 };
var clonedObj = { ...obj1 };
连接多个数组
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 将 arr2 中所有元素附加到 arr1 后面并返回
//等同于
var arr3 = arr1.concat(arr2);
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var mergedObj = { ...obj1, ...obj2 };
对象属性简写
当属性的对象命名和值的变量命名一致时,可以进行简写const name='Ming',age='18',city='Shanghai';
const student = {
name,
age,
city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
Promise
Promise 是异步编程的一种解决方案,比传统的解决方案callback更加的优雅。它最早由社区提出和实现的,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。// 不使用ES6
setTimeout(function()
{
console.log('Hello'); // 1秒后输出"Hello"
setTimeout(function()
{
console.log('Hi'); // 2秒后输出"Hi"
}, 1000);
}, 1000);
//使用ES6
var waitSecond = new Promise(function(resolve, reject)
{
setTimeout(resolve, 1000);
});
waitSecond
.then(function()
{
console.log("Hello"); // 1秒后输出"Hello"
return waitSecond;
})
.then(function()
{
console.log("Hi"); // 2秒后输出"Hi"
});
上面的的代码使用两个then来进行异步编程串行化,避免了回调地狱:
Let与Const
ES6推荐使用let声明局部变量,相比之前的var(无论声明在何处,都会被视为声明在函数的最顶部)let和var声明的区别:
var x = '全局变量';
{
let x = '局部变量';
console.log(x); // 局部变量
}
console.log(x); // 全局变量
let表示声明变量,而const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了
const a = 1
a = 0 //报错
如果const的是一个对象,对象所包含的值是可以被修改的。抽象一点儿说,就是对象所指向的地址没有变就行:
const student = { name: 'cc' }
student.name = 'yy';// 不报错
student = { name: 'yy' };// 报错
Array.prototype.includes()
includes() 函数用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回false
arr.includes(x)
//等价于
arr.indexOf(x) >= 0
指数操作符
console.log(2**10)
//等价于
console.log(Math.pow(2, 10));
async/await
在ES8中加入了对async/await的支持,也就我们所说的异步函数,这是一个很实用的功能。 async/await将我们从头痛的回调地狱中解脱出来了,使整个代码看起来很简洁。
async doLogin2(userName) {
const userId = await this.login(userName);
const result = await this.getData(userId);
}
使用Promise.all进行并发处理
async function charCountAdd(data1, data2) {
const [d1, d2] = await Promise.all([charCount(data1), charCount(data2)]);
return d1 + d2;
}
charCountAdd('Hello', 'Hi').then(console.log);
function charCount(data) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data.length);
}, 1000);
});
}
捕捉整个async/await函数的错误
async function charCountAdd(data1, data2) {
const d1 = await charCount(data1);
const d2 = await charCount(data2);
return d1 + d2;
}
charCountAdd('Hello','Hi')
.then(console.log)
.catch(e => console.log); //捕捉整个async/await函数的错误
捕捉单个的await表达式的错误
async function charCountAdd(data1, data2) {
const d1 = await charCount(data1)
.catch(e => console.log('d1 is null'));
const d2 = await charCount(data2)
.catch(e => console.log('d2 is null'));
return d1 + d2;
}
charCountAdd('Hello','Hi').then(console.log);
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.entries()
Object.entries()函数返回一个给定对象自身可枚举属性的键值对的数组。
//假设我们要遍历如下对象obj的所有属性的key和value
const obj = {a: 1, b: 2, c: 3};
//不使用Object.entries() :ES7
Object.keys(obj).forEach(key=>{
console.log(`key: ${key} value:${obj[key]}`);
})
//使用Object.entries() :ES8
for(let [key, value] of Object.entries(obj)){
console.log(`key: ${key} value:${value}`)
}
String padding
在ES8中String新增了两个实例函数String.prototype.padStart和String.prototype.padEnd,允许将空字符串或其他字符串添加到原始字符串的开头或结尾。
console.log('0.0'.padStart(4,'10')) //10.0
console.log('0.00'.padStart(20))// 0.00 常用于右对齐格式化
console.log('0.0'.padEnd(4,'0')) //0.00
console.log('0.0'.padEnd(10,'0'))//0.00000000
函数参数列表结尾允许逗号
var f = function(a, b,) {
...
}
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors() 函数用来获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
const obj2 = {
name: 'Jine',
get age() { return '18' }
};
Object.getOwnPropertyDescriptors(obj2)
// {
// age: {
// configurable: true,
// enumerable: true,
// get: function age(){}, //the getter function
// set: undefined
// },
// name: {
// configurable: true,
// enumerable: true,
// value:"Jine",
// writable:true
// }
// }
参考
标题:ES6、ES7、ES8特性
作者:iceuncle
地址:www.tianyang.pub/articles/20…