• ECMAscript6——2


    (5)Set数据结构

    ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

    Set本身是一个构造函数,用来生成Set数据结构。

    var s = new Set();

    [2,3,5,4,5,2,2].map(x => s.add(x))
    for (i of s) {console.log(i)}
    // 2 3 4 5

    上面代码表示,set数据结构不会添加重复的值。

    set数据结构有以下属性和方法:

    size:返回成员总数。
    add(value):添加某个值。
    delete(value):删除某个值。
    has(value):返回一个布尔值,表示该值是否为set的成员。
    clear():清除所有成员。
    s.add("1").add("2").add("2");
    // 注意“2”被加入了两次

    s.size // 2

    s.has("1") // true
    s.has("2") // true
    s.has("3") // false

    s.delete("2");
    s.has("2") // false
    (6)Map数据结构
    ES6还提供了map数据结构。它类似于对象,就是一个键值对的集合,但是“键”的范围不限于字符串,甚至对象也可以当作键。

    var m = new Map();

    o = {p: "Hello World"};
    m.set(o, "content")
    console.log(m.get(o))
    // "content"
    上面代码将一个对象当作m的一个键。

    Map数据结构有以下属性和方法:

    size:返回成员总数。
    set(key, value):设置一个键值对。
    get(key):读取一个键。
    has(key):返回一个布尔值,表示某个键是否在Map数据结构中。
    delete(key):删除某个键。
    clear():清除所有成员。
    var m = new Map();

    m.set("edition", 6) // 键是字符串
    m.set(262, "standard") // 键是数值
    m.set(undefined, "nah") // 键是undefined

    var hello = function() {console.log("hello");}
    m.set(hello, "Hello ES6!") // 键是函数

    m.has("edition") // true
    m.has("years") // false
    m.has(262) // true
    m.has(undefined) // true
    m.has(hello) // true

    m.delete(undefined)
    m.has(undefined) // false

    m.get(hello) // Hello ES6!
    m.get("edition") // 6
    (7).rest(...)运算符

    (1)基本用法

    ES6引入rest运算符(...),用于获取函数的多余参数,这样就不需要使用arguments.length了。rest运算符后面是一个数组变量,该变量将多余的参数放入数组中。

    function add(...values) {
    let sum = 0;

    for (var val of values) {
    sum += val;
    }

    return sum;
    }

    add(2, 5, 3) // 10
    上面代码的add函数是一个求和函数,利用rest运算符,可以向该函数传入任意数目的参数。

    下面是一个利用rest运算符改写数组push方法的例子。

    function push(array, ...items) {
    items.forEach(function(item) {
    array.push(item);
    console.log(item);
    });
    }

    var a = [];
    push(a, "a1", "a2", "a3", "a4");

    (2)将数组转为参数序列

    rest运算符不仅可以用于函数定义,还可以用于函数调用。

    function f(s1, s2, s3, s4, s5) {
    console.log(s1 + s2 + s3 + s4 +s5);
    }

    var a = ["a2", "a3", "a4", "a5"];

    f("a1", ...a)
    // a1a2a3a4a5

    从上面的例子可以看出,rest运算符的另一个重要作用是,可以将数组转变成正常的参数序列。利用这一点,可以简化求出一个数组最大元素的写法。

    // ES5
    Math.max.apply(null, [14, 3, 77])

    // ES6
    Math.max(...[14, 3, 77])

    // 等同于
    Math.max(14, 3, 77);

    上面代码表示,由于JavaScript不提供求数组最大元素的函数,所以只能套用Math.max函数,将数组转为一个参数序列,然后求最大值。有了rest运算符以后,就可以直接用Math.max了。

    (8)遍历器(Iterator)

    遍历器(Iterator)是一种协议,任何对象都可以部署遍历器协议,从而使得for...of循环可以遍历这个对象。

    遍历器协议规定,任意对象只要部署了next方法,就可以作为遍历器,但是next方法必须返回一个包含value和done两个属性的对象。其中,value属性当前遍历位置的值,done属性是一个布尔值,表示遍历是否结束。

    下面是一个无限运行的遍历器的例子。

    function idMaker(){
    var index = 0;

    return {
    next: function(){
    return {value: index++, done: false};
    }
    }
    }

    var it = idMaker();

    it.next().value // '0'
    it.next().value // '1'
    it.next().value // '2'
    // ...

    (9)generator函数

    ECMAscript6引入了genertor函数,作用就是返回一个内部状态的遍历器,主要特征是函数内部使用了yield语句。

     

    当调用generator函数的时候,该函数并不执行,而是返回一个遍历器(可以理解成暂停执行)。以后,每次调用这个遍历器的next方法,就从函数体的头部或者上一次停下来的地方开始执行(可以理解成恢复执行),直到遇到下一个yield语句为止,并返回该yield语句的值。

     

    ECMAScript 6草案定义的generator函数,需要在function关键字后面,加一个星号。然后,函数内部使用yield语句,定义遍历器的每个成员。

    yield有点类似于return语句,都能返回一个值。区别在于每次遇到yield,函数返回紧跟在yield后面的那个表达式的值,然后暂停执行,下一次从该位置继续向后执行,而return语句不具备位置记忆的功能。

    hw.next()
    // { value: 'hello', done: false }

    hw.next()
    // { value: 'world', done: false }

    hw.next()
    // { value: undefined, done: true }

    hw.next()
    // Error: Generator has already finished
    // at GeneratorFunctionPrototype.next (native)
    // at repl:1:3
    // at REPLServer.defaultEval (repl.js:129:27)
    // ...
    上面代码一共调用了四次next方法。

    第一次调用:函数开始执行,直到遇到第一句yield语句为止。next方法返回一个对象,它的value属性就是当前yield语句的值hello,done属性的值false,表示遍历还没有结束。

    第二次调用:函数从上次yield语句停下的地方,一直执行到下一个yield语句。next方法返回一个对象,它的value属性就是当前yield语句的值world,done属性的值false,表示遍历还没有结束。

    第三次调用:函数从上次yield语句停下的地方,一直执行到函数结束。next方法返回一个对象,它的value属性就是函数最后的返回值,由于上例的函数没有return语句(即没有返回值),所以value属性的值为undefined,done属性的值true,表示遍历已经结束。

    第四次调用:由于此时函数已经运行完毕,next方法直接抛出一个错误。

    遍历器的本质,其实是使用yield语句暂停执行它后面的操作,当调用next方法时,再继续往下执行,直到遇到下一个yield语句,并返回该语句的值,如果直到运行结束。

    function* f() {
    for(var i=0; true; i++) {
    var reset = yield i;
    if(reset) { i = -1; }
    }
    }

    var g = f();

    g.next() // { value: 0, done: false }
    g.next() // { value: 1, done: false }
    g.next(true) // { value: 0, done: false }

    上面代码先定义了一个可以无限运行的generator函数f,如果next方法没有参数,正常情况下返回一个递增的i;如果next方法有参数,则上一次yield语句的返回值将会等于该参数。如果该参数为true,则会重置i的值。

     

     

  • 相关阅读:
    每个人都有属于自己的机会
    [转]Android动画开发——Animation动画效果
    [转]android 使用WebView
    深圳 2012 职称英语 报名
    [转]java中的io笔记
    [转]手机蓝牙各类服务对应的UUID(常用的几个已通过验证)
    [文摘20111215]急事慢慢说
    [转]Android XML解析
    [转]J2SE复习笔记2线程
    queryScopedSelector
  • 原文地址:https://www.cnblogs.com/watchmen/p/5087239.html
Copyright © 2020-2023  润新知