ECMAScript 6是什么 #

ECMAScript 简称就是 ES ,你可以把它看成是一套标准, JavaScript 就是实施了这套标准的一门语言。 现在主流浏览器使用的是 ECMAScript 5 。 ECMAScript6被称为ECMAScript2015,是2015年出版的新版本,是ES5的一次改进。

ECMAScript 6特点 #

增加了许多必要的特性,例如模块和类,块作用域,常量和变量

1.块级作用域变量-let #

作用域就是一个变量的作用范围。也就是你声明一个变量以后,这个变量可以在什么场合下使用 以前的JavaScript只有全局作用域,还有函数作用域 现在JavaScript也有了块级作用域,用一组大括号定义一个块,使用 let 定义的变量在大括号的外面是访问不到的

{
    let a = 100;
}
console.log(a); //Uncaught ReferenceError: a is not defined

1.1 实例1: #

for(let i = 0; i<10 ;i++){
    setTimeout(function () {
        console.log(i);
    }, 1000);
}

1.2 实例2: #

var btns = document.getElementsByTagName('button');
for(let i = 0; i<btns.length;i++){
    btns[i].onclick = function () {
        alert(i);
    }
}

2.常量-const #

也会创建一个块级作用域

{
    const names = 'zfpx';
}
alert(names); //Uncaught ReferenceError: names is not defined

使用const我们可以去声明一个常量,常量一旦赋值就不能再修改

const names = 'zfpx';
names = 'jw'; //Uncaught TypeError: Assignment to constant variable.

注意const限制的是不能给变量重新赋值,而引用类型仍可以操作指向的空间

const name = {
    hello : 'zfpx'
};
name.hello = 'hello zfpx';

3.解构赋值 #

解构意思就是分解一个东西的结构,可以把组中的值依次赋值给一组变量

3.1 解析数组 #

let ary = [1,2,3];
let [a,b,c] = ary;
console.log(a,b,c);

3.2 解析对象 #

let obj = {name:'zfpx',age:7}
let {name,age} = obj;
console.log(name,age);

3.3 变量的重命名 #

let obj = {name:'zfpx',age:7}
let {name:a,age:b} = obj;
console.log(a,b);

4.模板字符串 #

4.1 模板字符串用反引号 #

(数字1左边的那个键)包含,其中的变量用${}括起来

let name = 'zfpx';
let age = '7';
let str = `${name} 今年 ${age} 岁`;
console.log(str);

其中的变量会用变量的值替换掉

4.2 带标签的模板字符串 #

可以在模板字符串的前面添加一个标签,这个标签可以去处理模板字符串 标签其实就是一个函数,函数可以接收两个参数,一个是strings,就是模板字符串里的每个部分的字符 还有一个参数可以使用rest的形式values,这个参数里面是模板字符串里的值

var name = 'zfpx',age = 7;
function funcName(string,...values){
    console.log(string,values);
}
funcName`你好 ${name} 你今年 ${age} 岁了`;

4.3 字符串新方法 #

let desc = 'zfpx is 7 years old';
console.log(desc.endsWith('old')); //字符串是否以`old`结尾
console.log(desc.startsWith('zfpx'));// 字符串是否以`zfpx`开头
console.log(desc.includes('is'));//字符串是否包含`is`

5.函数 #

5.1 默认参数 #

可以给函数的参数设置默认值 在执行这个函数的时候,如果不指定函数的参数的值,就会使用参数的这些默认的值 若参数传入undefined,则认为该参数等于默认值

let func = function (name='zfpx',age=7) {
    console.log(name,age);
};
func(undefined);

5.2 扩展运算符 #

把...放在数组前面可以把一个数组进行展开,可以把一个数组直接传入一个函数而不需要使用apply

let func = function (name='zfpx',age=7) {
    console.log(name,age);
};
func(...['珠峰培训',7]);

5.3 剩余操作符 #

剩余操作符可以把其余的参数的值都放到一个叫item的数组里面

var arr = [];
let func = function (arr,...item) {
    console.log(item);
}
console.log(func(arr,1,2,3));

5.4 解构参数 #

对象

let func = function ({param1:A,param2:B}) {
    console.log(A,B);
};
func({param1:'zfpx',param2:'7'});

数组

let func1 = function ([param1,param2]) {
    console.log(param1,param2);
};
func1(['zfpx',7]);

5.5 获取函数名字 #

ECMAScript 6 给函数添加了一个name属性

let a = function func() {}
console.log(a.name);

5.6 箭头函数 #

箭头函数简化了函数的的定义方式,一般以 "=>" 操作符左边为输入的参数,而右边则是进行的操作以及返回的值inputs=>output

[1,2,3].forEach(val => console.log(val));

输入参数如果多于一个,要用()包起来,函数体如果有多条语句需要用{}包起来

[1,2,3].forEach((val,index) => {
    console.log(val,index);
});

箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。 正是因为它没有this,从而避免了this指向的问题。

var arrowObj = {
    obj:{name:1},
    func: function () {
        setTimeout(()=>console.log(this.obj.name),2000)
    }
};
arrowObj.func();

6.对象 #

6.1 对象字面量 #

如果你想在对象里添加跟变量名一样的属性,并且属性的值就是变量表示的值,就可以直接在对象里加上这些属性

let name = 'zfpx';
let age = '7';
let school = {
    name,
    age
};
console.log(school);

6.2 Object.is #

对比两个值是否相等

console.log(Object.is(0,-0));

6.3 Object.assign #

把多个对象的属性复制到一个对象中,第一个参数是复制的对象,从第二个参数开始往后,都是复制的源对象

var name1 = {name:'zfpx'};
var age = {age:7};
var obj = {};
Object.assign(obj,name1,age);
console.log(obj);

6.4 Object.setPrototypeOf #

将一个指定的对象的原型设置为另一个对象

var proto = {name:1};
var obj = {};
Object.setPrototypeOf(obj,proto);
console.log(obj.name);
console.log(Object.getPrototypeOf(obj));

6.5 proto #

var proto = {name:1};
var obj = {
    __proto__:proto
};
console.log(obj.name);
console.log(Object.getPrototypeOf(obj));

6.6 super #

var obj2 = {
     eat:(who)=>{
        console.log(who+'吃');
    }
};
var obj = {
    __proto__:obj2,
    eat(){
        super.eat('我');
    }
};
obj.eat();

7.生成器与迭代器 #

7.1 Interator 迭代器 #

迭代器有一个next方法,每次执行的时候会返回一个对象 对象里面有两个属性,一个是value表示返回的值,还有就是布尔值done,表示是否迭代完成

function buy(item){
    let len = 0;
    return {
        next(){
            let done = len ==item.length;
            let value = item[len]?item[len++]:undefined;
            return {
                done,value
            }
        }
    }
}
var interator = buy(['html','js']);
do{
    var cur = interator.next();
    console.log(cur);
}while(!cur.done);

7.2 Generators 生成器 #

function* buy(items){
    for(var i =0; i<items.length;i++){
        yield items[i];
    }
}
var interator = buy(['html','js']);
do{
    var cur = interator.next();
    console.log(cur);
}while(!cur.done);

8.类 #

8.1 class #

使用class这个关键词定义一个类,基于这个类创建实例以后会自动执行constructor方法,此方法可以用来初始化

class Person {
    constructor(name){
        this.name = name;
    }
    getName(){
        return this.name;
    }
    setName(val){
        this.name = val;
    }
}
let person = new Person('zfpx');
person.setName('zhufeng');
console.log(person.getName());

8.2 get与set #

getter可以用来得获取属性,setter可以去设置属性

class Person {
    constructor(name){
        this.name = name;
    }
    set person(val){
        this.name = val;
    }
    get person(){
        return this.name;
    }
}
let p = new Person('zfpx');
p.person = 'zhufeng';
console.log(p.name);

8.3 静态方法-static #

在类里面添加静态的方法可以使用static这个关键词,静态方法就是不需要实例化类就能使用的方法

class Person {
    static add(name,age){
        console.log(name,age);
    }
}
Person.add('zfpx',7);

8.4 继承extends #

一个类可以去继承其它的类里的东西

class Parent{
    constructor(name){
        this.name = name;
    }
}
class Child extends Parent{
    constructor(name,age){
        super(name);
        this.age = age;
    }
}
let c = new Child('zfpx',7);
console.log(c.name, c.age);

9.Set #

一个Set是一堆东西的集合,Set有点像数组,不过跟数组不一样的是,Set里面不能有重复的内容

var set = new Set();
set.add('hello');
set.add('hello');//不能增加相同集合
console.log(set.has('hello'));//是否包含哪个集合
console.log(set.size);//集合的长度
set.add('world');
set.forEach(function (item) {
    console.log(item);
});
set.delete('hello');//删除集合
set.clear();//清空set
console.log(set);

10.Map #

可以使用 Map 来存放这种键值对的数据

var map = new Map();
map.set('zfpx',{name:'zfpx'});//添加键值对
map.set('age',{age:7});
map.forEach(function (item) { //循环键值对
    console.log(item);
});
console.log(map.size); //Map的长度
console.log(map.has('zfpx'));//是否存在
map.delete('zfpx'); //删除
console.log(map);
map.clear(); //清空

11.模块 #

可以根据应用的需求把代码分成不同的模块 每个模块里可以导出它需要让其它模块使用的东西 在其它模块里面可以导入这些模块导出的东西

11.1 模块 #

在页面中引用

<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
<script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
<script type="module"  src="./2.js"></script>

导出1.js

'use strict';
export var name = 'zfpx';
export var age = 8;

在2.js中导入1.js

import * as school from './1.js';
console.log(school.name);
console.log(school.age);

import {name,age} from './1.js';
console.log(name);
console.log(age);

11.2 重命名 #

导出模块时重命名

function hello(){
    console.log('hello zfpx');
}
export {hello as hello2};

导入模块时重命名

import {hello2 as helloe} from './1.js';

默认导出 每个模块都可以有一个默认要导出的东西

export default function say(){
    console.log('say');
}

使用模块

import say1 from './1.js';