2.1 Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

大家可以这样记:

USONB

u: undefined

s : string symbol

o: object

n: null number

b: boolean

非常的简便。

Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

基本语法:

<script>
        let k = Symbol();
        console.log(typeof k);
</script>

输出结果为symbol。

注意:Symbol函数前不能用new命令。因为Symbol的值不是对象,所以不能添加属性。

Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

<script>
        let s1 = Symbol('foo');
        let s2 = Symbol('bar');
        console.log(s1);  // Symbol(foo)
        console.log(s2); // Symbol(bar)
        console.log(s1.toString()); // "Symbol(foo)"
        console.log(s2.toString()); // "Symbol(bar)"
</script>




es bool 下面可以写 has_child 吗_Powered by 金山文档


上面代码中,s1和s2是两个 Symbol 值。如果不加参数,它们在控制台的输出都是Symbol(),不利于区分。有了参数以后,就等于为它们加上了描述,输出的时候就能够分清,到底是哪一个值。

作为属性名的 Symbol:

由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

有很多种写法,我们一起来看看:

<script>
        let mySymbol=Symbol();
        //第一种
        let a = {};
        a[mySymbol]='hello';
        //第二种
        let b ={
            [mySymbol]:'hello'
        };
        //第三种
        let c = {};
        Object.defineProperty(c,mySymbol,{value:'hello'})
        console.log(a);
        console.log(b);
        console.log(c);
</script>


es bool 下面可以写 has_child 吗_es6_02


大家可以看出得到的结果是一致的。

2.2 迭代器

遍历器(iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。

1)

2)原生具备 iterator 接口的数据(可用 for of 遍历)

Array Arguments Set Map String TypeArry NodeList

3)工作原理

a)创建一个指针对象,指向当前数据结构的起始位置

b) 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员

c) 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员

d)每调用 next 方法返回一个包含 value 和 done 属性的对象

注意:需要自定义遍历数据的时候,要想到迭代器。

<script>
        //声明一个数组
        const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧'];
        let iterator = xiyou[Symbol.iterator]();
        //调用对象的next方法
        console.log(iterator);
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
</script>


es bool 下面可以写 has_child 吗_前端_03


es bool 下面可以写 has_child 吗_数据结构_04


es bool 下面可以写 has_child 吗_Powered by 金山文档_05


为对象添加iterator接口:

<script>
        //声明一个对象
        const banji = {
            name: "终极一班",
            stus: [
                'xiaoming',
                'xiaoning',
                'xiaotian',
                'knight'
            ],
            [Symbol.iterator]() {
                //索引变量
                let index = 0;
                //
                let _this = this;
                return {
                    next: function () {
                        if (index < _this.stus.length) {
                            const result = { value: _this.stus[index], done: false };
                            //下标自增
                            index++;
                            //返回结果
                            return result;
                        } else {
                            return { value: undefined, done: true };
                        }
                    }
                };
            }
        }

        //遍历这个对象 
        for (let v of banji) {
            console.log(v);
        }
</script>


es bool 下面可以写 has_child 吗_javascript_06


2.3 生成器

生成器函数(function *)是ES6提供的一种异步编程解决方案,语法和传统函数大不相同。生成器函数简单理解就是这个函数返回一个可枚举的对象(官方说法返回Generator

<script>
        function * gen() {
            yield '你好';
            yield '你真好';
            yield '你太好了';
        }
        let iterator = gen();
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
</script>


es bool 下面可以写 has_child 吗_javascript_07


注意:

  1. *的位置没有限制,靠近左边、右边、中间都可以。
  2. 生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yield语句中的值。
  3. yield相当于函数的暂停标记,也可以认为是函数的分隔符,每一次调用next方法,都会执行一次。
  4. next方法可以传递实参,作为yield的返回值。

2.4 promise

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

1)Promise 构造函数: Promise (excutor) {}

2)Promise.prototype.then 方法

3)Promise.prototype.catch 方法

promise基本语法:

<script>
        //实例化promise对象
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                // let data = '用户数据';
                // resolve(data);
                let err = '失败';
                reject(err);
            }, 1000)
        });
        //调用promise对象的then方法
        p.then((value) => {
            console.log(value);
        }, (reason) => {
            console.error(reason);
        })
</script>

调用resolve生成的结果。


es bool 下面可以写 has_child 吗_数据结构_08


调用reject生成的结果。


es bool 下面可以写 has_child 吗_前端_09


promise-then 方法:

<script>
        //创建promise对象
        const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('用户数据');
                // reject('出错了');
            }, 1000)
        })
        //调用then方法,then方法的返回结果是promise对象,对象状态由回调函数所执行的结果决定
        //如果回调函数返回的结果是‘非promise’属性,promise状态为成功,返回的值为对象成功的值
        p.then(value => {
            console.log(value);
            return 521;
        }, reason => {
            console.warn(reason);
        })
</script>

promise-catch 方法:

<script>
        const p =new Promise((resolve,reject)=>{
            setTimeout(()=>{
                reject('失败了');
            })
        },1000)
    
        p.catch(function(reason){
            console.warn(reason);
        })
</script>


es bool 下面可以写 has_child 吗_javascript_10


2.5 Set

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:

  1. size 返回集合的元素个数
  2. add 增加一个新元素,返回当前集合。
  3. delete 删除元素,返回布尔值
  4. has 检测集合中师傅包含某个元素,结果返回布尔值。
  5. clear 清空集合,返回undefined。
<script>
        //声明一个 set
        let s = new Set();
        let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);

        //元素个数
        console.log(s2.size);
        //添加新的元素
        s2.add('喜事儿');
        //删除元素
        s2.delete('坏事儿');
        //检测
        console.log(s2.has('糟心事'));
        //清空
        s2.clear();
        console.log(s2);

        for(let v of s2){
            console.log(v);
        }
        
</script>

set 集合实践

//数组去重
let arr = [1,2,3,4,5,4,3,2,1];
        //数组去重
        let result = [...new Set(arr)]
        console.log(result);


es bool 下面可以写 has_child 吗_数据结构_11


//交集
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
        //交集
        let arr1 = [4, 5, 6, 2, 3];
        let result = [...new Set(arr)].filter(function (item) {
            let s = new Set(arr1);
            if (s.has(item)) {
                return true;
            } else {
                return false;
            }
        });
        console.log(result);


es bool 下面可以写 has_child 吗_es6_12


//并集
 let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
        let arr1 = [4, 5, 6, 2, 3];
        //先合并数组再进行去重
        let newArr = [...new Set([...arr,...arr1])];
        console.log(newArr);


es bool 下面可以写 has_child 吗_数据结构_13


//差集
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
        let arr1 = [4, 5, 6, 2, 3];
        let cha = [...new Set(arr)].filter(item => !(new Set(arr1).has(item)));
        console.log(cha);


es bool 下面可以写 has_child 吗_Powered by 金山文档_14


2.6 Map

因为JavaScript中的对象,本质上是键值对的集合,但是传统上只能用字符串当作键,这意味着带来了很大的限制。

为了解决这个问题,ES6向我们提供了Map这种数据结构,他类似于对象,但是键的范围不限于字符串,大多数数据类型的值都可以当作键,所以如果需要键值对的数据结构Map比Object更加合适。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属性和方法:

  1. size 返回Map的元素个数。
  2. set 增加一个新元素,返回给Map.
  3. get 返回键名对象的键值。
  4. has 检测Map中是否包含某个元素,返回布尔值。
  5. clear 清空集合,返回undefined。

声明Map:

let m = new Map()

添加元素:

let m = new Map()

        m.set('name', 'XATU');
        m.set('change', function () {
            console.log('兵工七子');
        })
        console.log(m);


es bool 下面可以写 has_child 吗_前端_15


删除元素:

m.set('name', 'XATU');
        m.set('change', function () {
            console.log('兵工七子');
        })
        m.delete('change');
        console.log(m);


es bool 下面可以写 has_child 吗_javascript_16


获取get:

//声明Map
        let m = new Map()

        m.set('name', 'XATU');
        m.set('change', function () {
            console.log('兵工七子');
        })
        // m.delete('change');
        console.log(m.get('name'));


es bool 下面可以写 has_child 吗_Powered by 金山文档_17


清空 clear:

m.clear();

遍历:

let m = new Map()

        m.set('name', 'XATU');
        m.set('change', function () {
            console.log('兵工七子');
        })
        for (let k of m) {
            console.log(k);
        }
        console.log(m);


es bool 下面可以写 has_child 吗_Powered by 金山文档_18


2.7 class

通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

class Shouji{
        constructor(brand,price){
            this.brand=brand;
            this.price=price;
        }
        call(){
            console.log('我可以打电话');
        }
       }
       let mi = new Shouji('小米','1999')
       console.log(mi);