ES6的一些新特性

现代浏览器的迅速支持,促使ES6基本成为业界标准。我们今天就来聊一下它的这些新特性:

  • Let与Const声明
  • 模板字符串
  • 对象属性简写
  • for...of和for...in
  • Symbol数据类型
  • 解构赋值
  • Set和Map
  • 箭头函数
  • ES6的扩展
  • Promise
  • Class类
  • 模块化

一、 Let与Const声明

传统var声明的一大局限是变量污染,比如内层变量可能覆盖外层变量,在if或for循环中声明的变量会泄露成全局变量。
为了解决这个问题,ES6引入了let和const命令来进行变量声明。来看下它们的特点和区别:

var——会被视为声明在函数最顶部,有变量提升特性
let——声明局部变量,没有变量提升特性
const——声明常量,声明时必须赋值,且一旦赋值就不能再修改,除非const的是一个对象(对象包含的值可以修改,修改方法见下图)。

const student = { name: 'cc' }
student.name = 'yy';// 不报错
student  = { name: 'yy' };// 报错

二、模板字符串

将表达式嵌入字符串中进行拼接。只要将变量放在${}内即可,整个模板字符串用``包裹起来。

var name = "Lucy", age = 16;
`My name is ${name}, I'm ${age}, I can write like this —— ${name+age}.`

三、对象属性简写

设置对象属性时可以不指定属性名:

const name = 'Ming',
age = '18',
city = 'Shanghai';
const student = {
  name,
  age,
  city
};
console.log(student);

四、for...of和for...in

1、for...of遍历迭代器,如数组:

let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
  console.log(letter);  // 结果: a, b, c
}

2、for...in遍历对象属性:

 let stus = ["Sam", "22", "男"];
 for (let stu in stus) {
   console.log(stus[stu]);  // 结果: Sam, 22, 男
  }

五、Symbol数据类型

用来定义独一无二的值,通过Symbol('字符串')函数来生成。如下图s1和s2,看似一样实则不同:

let s1 = Symbol('web');
let s2 = Symbol('web');
console.log(s1 === s2);
console.log(typeof s1);
console.log(typeof s2);

因为它的值都不相等,所以可以作为对象属性名,有三种方式可以实现——直接赋值、[symbol]、defineProperty(),栗子如下:

// 第一种:直接赋值
let symbol = Symbol();
let a = {};
a[symbol] = 'web';
// 第二种:[symbol]属性
let symbol = Symbol();
let a = {
    [symbol]: 'web'
}
// 第三种:defineProperty
let symbol = Symbol();
let a = {};
Object.defineProperty(a, symbol, {value: 'web'});

获取Symbol属性,可以使用Object.getOwnPropertySymbols()。

六、解构赋值

从数组或对象中提取值,对变量进行赋值。要求等号两边的模式相同。

1、使用方法
  • 获取数组中的值
var foo = ["one", "two", "three", "four"];
var [one, two] = foo;
console.log(one);
console.log(two);
console.log(three);

var [first, , , last] = foo;
console.log(first);
console.log(last);

var a, b; [a, b] = [1, 2];
console.log(a);
console.log(b);
  • 可以方便地交换两个变量的值
var a = 1;
var b = 3; [a, b] = [b, a];
console.log(a);
console.log(b);
  • 获取对象中的值
const student = {
  name: 'Ming',
  age: '18',
  city: 'Shanghai'
};
const {
  name,
  age,
  city
} = student;
console.log(name);
console.log(age);
console.log(city);
2、需要注意的问题:
  • 不能用undefined赋值。
let [x=1] = [undefined];
x;  // 1
  • 注意变量作用域问题
let x;
{x} = {x: 1};  // 这里的大括号外要加小括号

七、Set和Map

Set类似数组,Map类似对象,但它们都没有重复的值,可以进行去重操作。

1. 声明方式

new Set();和 new Map();

let a = new Set([1,2,3,4,5]);
let b = new Map([
    ['name', 'web'],
    ['des', 'js']
])
2. 共有属性

(1)constructor:构造函数
(2)size:元素个数,代替数组的length

3. 操作方法

(1)共有的:delete、has、clear

let a = new Set([1,2,3,4]);
a.delete(2);
console.log(a);  // [1,3,4]
console.log(a.has(3)); // true
a.clear();   // Set(0){}
a.add(6);

(2)Set独有的方法:add()——添加新元素
(3)Map独有的方法
A. set(key, value)——添加新元素
B. get(key)——查找特定数值并返回

3. 共有的遍历方法
  • keys()——返回所有键
  • values()——返回所有值
  • entries()——返回键值对
  • forEach(callbackFn, thisArg)——执行callbackFn操作

八、箭头函数

箭头函数有这样几个特点:

1.不需要function关键字,继承当前上下文的this关键字。
2.只有一个参数时,可以省略();
3.只返回一个表达式时,可以省略{}和return。
4.没有arguments变量
5.不会改变this指向——箭头函数没有自己的this,函数内部的this就是外层代码块的this,举个栗子:

var person = {
    name: "Lucy",
    age: 16,
    func: ()=>{
        console.log(this);
    }
}
person.func(); // window对象

可以发现this是window对象,如果改为普通函数,this指的就是person对象。
那么是不是箭头函数可以完全取代普通函数呢?
并非如此,定义对象时和需要动态this时,不能使用箭头函数。

九、ES6的扩展

ES6在函数、对象、数组对ES5进行了扩展。

1. 函数扩展

(1)默认值:||后 ---> 参数定义后

// es5
function log(x,y) {
    y = y || 'web';
    console.log(x,y);
}
// es6
function log(x,y="web"){
    console.log(x,y);
}

(2)剩余运算符: ...arr表示参数

function web(...arr){
    for(let item of arr){
        console.log(item);
    }
}
web(1,2,3,4,5);

(3)扩展运算符

function add(a,b,c) {
    console.log(a);
    console.log(b);
    console.log(c);
}
var arr = [1,2,3];
add(...arr);
2. 对象的扩展

(1)直接向对象写入变量和函数作为对象的属性和方法
(2)可以使用表达式作为对象的属性
(3)setter和getter
ES6对象的操作方法:
Object.is():比较两个值是否相等。
Object.assign():用于将对象进行合并。Object.getOwnPropertyDescriptor:返回对象属性的描述。
Object.keys()返回一个数组,包含对象自身所有的可枚举属性。

3. 数组的扩展

(1)copyWithin(target,start,end):在当前数组内部,将指定位置的成员复制到其他位置,然后返回当前数组。
(2)target——从该位置开始替换数据。负值表示倒数。
(3)start——从该位置开始读取数据,默认为0。负值表示倒数。
(4)end——到该位置前停止读取数据,默认等于数组长度。负值表示倒数。
(5)find()——找出第一个符合条件的数组成员。
(6)findIndex()——返回第一个符合条件的数组成员的位置,都不符合条件则返回-1。
(7)fill()——填充一个数组,可用于空数组的初始化。
(8)includes()——数组是否包含给定值。

4. 字符串的扩展

(1)s.includes(str)——是否找到了str
(2)s.startsWith(str)——str是否在s的开始位置
(3)s.endsWith(str)——str是否在s的结束位置
它们都支持第2个参数(整型),表示开始匹配的位置

十、Promise

Promise对象表示异步操作的最终状态。它是异步编程的一种解决方案,可以将异步操作用同步操作的流程表达出来,避免层层嵌套,并且提供统一的接口,更方便控制异步操作。
Promise构造函数接收一个函数作为参数,这个函数又有两个参数分别是resolve和reject,如下:

const promiseObj = new Promise(function(resolve,reject){
    // code
    if(/*异步操作成功*/){
        resolve(value);
    }else{
        reject(error);
    }
})

Promise实例生成后,可以用then方法分别指定resolved状态和rejected状态的回调函数。这两个回调函数都接收Promise对象传出的值作为参数,其中第一个回调函数在Promise对象状态变为resolved时调用,第二个在rejected状态时调用(第二个回调函数可选),来段代码:

promiseObj.then(function(value){},function(error){})

十一、Class类

ES6引入Class类,让js的面向对象编程更简单和易于理解。可以使用class构造对象,二是可以使用extends实现继承。

class Point{
    constructor(x,y){
        this.x = x;  // 初始化
        this.y = y;
    }
    toString(){
        return `(${this.x},${this.y})`;
    }
}
let p = new Point(10,20);
console.log(p.x, p.y);
console.log(p.toString());

// 继承
class ColorPoint extends Point{
    constructor(x,y,color){
        super(x,y);
        this.color = color;
    }
    showColor(){
        console.log('这个点的颜色是'+this.color);
    }
}
let cp = new ColorPoint(30,40,'red');
console.log(cp.x, cp.y);
console.log(cp.toString());
cp.showColor();

十二、模块化

模块的功能主要由 export 和 import 组成。每个模块都有自己单独的作用域,通过 export 来规定对外暴露的接口,通过import引用其它模块提供的接口。

1、export导出

可以使用export导出多个变量或函数

  • 导出变量/常量
export var name = 'Rainbow';  // 导出变量
export const sqrt = Math.sqrt;  // 导出常量
  • 导出多个变量
var name = "Rainbow";
var age = 24;
export {
  name,
  age
}
  • 导出函数
export function supModule(args){
  return args;
}
2、import导入

定义好模块的输出以后就可以在另一个模块引用了。

  • 一条import 语句可以同时导入默认函数和其它变量
import testMethod, {otherMethod} from 'xxx.js';
  • 可以为变量起别名
import { otherMethod as om } from 'xxx.js'

十三、其他高级用法

1. Iterator遍历器

它可以为各种数据结构提供统一接口。

2. Genera函数

也是一种异步编程解决方案,返回一个遍历器对象,可以依次遍历Generator函数的每个状态。

你可能感兴趣的:(ES6的一些新特性)