zoukankan      html  css  js  c++  java
  • ES6

    ES6教程

    对象字面量

    • 方法属性

        let obj = {
            // before
            foo: function() {
                return 'foo'
            },
      
            // after
            bar() {
            return 'bar'
            }
        }
      
    • proto

        let o = {
            __proto__: new Foo()
        }
      
    • 属性名动态计算

        let arr = [1, 2, 3]
        let outArr = arr.map(n => {
            return {
              [ n ]: n,
              [ `${n}^2` ]: Math.pow(n, 2)
        }
        })
        console.dir(outArr) //=>
          [
            { '1': 1, '1^2': 1 },
            { '2': 2, '2^2': 4 },
            { '3': 3, '3^2': 9 }
        ]
      
    • 同名方法属性省略

            // module.js
            export default {
              someMethod
            }
      
            function someMethod() {
                // ...
            }
      
            // app.js
            import Module from './module'
      
            Module.someMethod()
      

    const

    let

    产生块级作用域

        for (let i = 0; i < buttons.length; i++) {
            // ...
        }
    

    for-of循环

    • ES5中的循环(不能响应break,continue,return)

        myArray.forEach(function (value) {
        console.log(value);
        });
      
    • for-in(遍历属性)

    • 属性遍历

        for (var key of Object.keys(someObject)) {
        console.log(key + ": " + someObject[key]);
        }
      
    • for-of(为各种集合遍历数据如数组,可以响应break,continue,return,不只可以遍历数组)

        //遍历数组
        for (var value of myArray) {
        console.log(value);
        }
        //遍历字串
        for (var chr of "") {
        alert(chr);
        }
        //遍历set对象
        var uniqueWords = new Set(words);
        for (var word of uniqueWords) {
        console.log(word);
        }
        //遍历并解构map对象(map对象是键值对)
        for (var [key, value] of phoneBookMap) {
        console.log(key + "'s phone number is: " + value);
        }
      
    • 迭代器(实现迭代器方法就可以对对象使用for-of)

        // 使jQuery支持for-of
        jQuery.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
      

      for-of循环时会调用集合的[Symbol.iterator](),返回新的迭代器对象

      迭代器对象.next(),next()被反复调用

        var zeroesForeverIterator = {
           [Symbol.iterator]: function () {
              return this;
           },
           next: function () {
                return {done: false, value: 0};//无限循环,只返回0
           },
           return:function(){...}
          
        };
      

      迭代器对象.return(),过早退出会触发return(),异常,break,return会触发过早退出

      for-of执行过程:

        var $iterator = ITERABLE[Symbol.iterator]();
        var $result = $iterator.next();
        while (!$result.done) {
          VAR = $result.value;
          一些语句
          $result = $iterator.next();
        }
      

    生成器 Generators

    生成器在执行过程中遇到yield时会暂停执行(生成器的堆栈结构包括本地变量,参数,临时值,当前执行位置会被移出堆栈,生成器对象会保留对这个堆栈的引用),在调用next()时重新激活堆栈结构并继续执行
    yield不是退出而是切出

        //定义生成器
        function* quips(name) {
                yield "你好 " + name + "!";
                yield "希望你能喜欢这篇介绍ES6的译文";
                if (name.startsWith("X")) {
                yield "你的名字 " + name + "  首字母是X,这很酷!";
                }
                yield "我们下次再见!";
        }
        //执行
        > var iter = quips("jorendorff");
        [object Generator]
        > iter.next()
        { value: "你好 jorendorff!", done: false }
        > iter.next()
        { value: "希望你能喜欢这篇介绍ES6的译文", done: false }
        > iter.next()
        { value: "我们下次再见!", done: false }
        > iter.next()
        { value: undefined, done: true }
    

    生成器就是迭代器,生成器内建next()和[Symbol.iterator]()方法的实现,可以构建出永无止境的序列的生成器。

        //传统迭代器的构建
        class RangeIterator {
                constructor(start, stop) {
                        this.value = start;
                        this.stop = stop;
                }
                
                [Symbol.iterator]() { return this; }
                
                next() {
                        var value = this.value;
                        if (value < this.stop) {
                           this.value++;
                           return {done: false, value: value};
                        } else {
                           return {done: true, value: undefined};
                        }
                }
        }
        
        // 返回一个新的迭代器,可以从start到stop计数。
        function range(start, stop) {
            return new RangeIterator(start, stop);
        }
        
        //用生成器来构建迭代器
        function* range(start, stop) {
         for (var i = start; i < stop; i++)
           yield i;
         }
    
        //生成器构建filter
        function* filter(test, iterable) {
          for (var item of iterable) {
           if (test(item))
               yield item;
          }
        }
    
        //生成器用于异步
        // 制造一些噪音的异步代码。
        // 返回一个Promise对象
        // 当我们制造完噪音的时候会变为resolved
        function makeNoise_async() {
        return Q.async(function* () {
        yield shake_async();
        yield rattle_async();
        yield roll_async();
        });
        }
    

    template strings

    用``代替'',支持多行

        function authorize(user, action) {
          if (!user.hasPrivilege(action)) {
                throw new Error(
                `用户 ${user.name} 未被授权执行 ${action} 操作。`);// ${action}模板占位符
           }
        }
    

    标签模板(tagged templates)

        var message =SaferHTML`<p>${bonk.sender} 向你示好。</p>`;
        //等同于
        var message =SaferHTML(templateData, bonk.sender);
        function SaferHTML(templateData) {//templateData   Object.freeze(["<p>", " has sent you a bonk.</p>"] 不可变数组
          var s = templateData[0];
          for (var i = 1; i < arguments.length; i++) {
            var arg = String(arguments[i]);
    
            // 转义占位符中的特殊字符。
            s += arg.replace(/&/g, "&")
                    .replace(/</g, "<")
                    .replace(/</g, ">");
    
            // 不转义模板中的特殊字符。
            s += templateData[i];
          }
          return s;
        }
        
        
        // 基于纯粹虚构的模板语言
        // ES6标签模板。
        var libraryHtml = hashTemplate`
          <ul>
            #for book in ${myBooks}
              <li><i>#{book.title}</i> by #{book.author}</li>
            #end
          </ul>
        `;
    

    不定参数,默认参数

    • 不定参数

      //传统方法
      

      function containsAll(haystack) {
      for (var i = 1; i < arguments.length; i++) {
      var needle = arguments[i];
      if (haystack.indexOf(needle) === -1) {
      return false;
      }
      }
      return true;
      }
      //ES6实现方法
      //...needles为不定参数,必须在最后一位,参数传入时会赋一个数组,类似["b", "nan"],没有参数时[]
      function containsAll(haystack, ...needles) {
      for (var needle of needles) {
      if (haystack.indexOf(needle) === -1) {
      return false;
      }
      }
      return true;
      }
      //调用
      containsAll("banana", "b", "nan")

    • 默认参数

      //参数自左向右求值,可以使用赋好值的其他参数 
      function animalSentenceFancy(animals2="tigers",animals3=(animals2 == "bears") ? "sealions" : "bears")
      {
              return `Lions and ${animals2} and ${animals3}! Oh my!`;
      }
      
      animalSentenceFancy("bears") //“Lions and bears and sealions. Oh my!”
      
      //undefined相当于不传值
      animalSentence(undefined, "unicorns") //“Lions and tigers and unicorns! Oh my!
      

    解构Destrucuring

    • 数组的结构([ variable1, variable2, ..., variableN ] = array;)

        var first = someArray[0];
        var second = someArray[1];
        var third = someArray[2];
        //解构
        var [first, second, third] = someArray;
        //嵌套结构
        var [foo, [[bar], baz]] = [1, [[2], 3]];
        //跳过其他元素
        var [,,third] = ["foo", "bar", "baz"];
        //不定参数结构
        var [head, ...tail] = [1, 2, 3, 4];
        console.log(tail);
        // [2, 3, 4]
        
        // undefined
        var [missing] = [];
        console.log(missing);
        
        
        
        function* fibs() {
        var a = 0;
        var b = 1;
        while (true) {
        yield a;
        [a, b] = [b, a + b];
        }
        }
        var [first, second, third, fourth, fifth, sixth] = fibs();
        console.log(sixth);
        // 5
      
    • 对象的解构

        var robotA = { name: "Bender" };
        var robotB = { name: "Flexo" };
        var { name: nameA } = robotA;
        var { name: nameB } = robotB;
        console.log(nameA);
        // "Bender"
        console.log(nameB);
        // "Flexo"
      
        //属性名与变量名一致时
        var { foo, bar } = { foo: "lorem", bar: "ipsum" };
        console.log(foo);
        // "lorem"
        console.log(bar);
        // "ipsum"
      
        //嵌套解构
        var complicatedObj = {
        arrayProp: [
                "Zapp",
                { second: "Brannigan" }
        ]
        };
        var { arrayProp: [first, { second }] } = complicatedObj;
        console.log(first);
        // "Zapp"
        console.log(second);
        // "Brannigan"
      
    • 解构的默认值

        var [missing = true] = [];
        console.log(missing);
        // true
        var { message: msg = "Something went wrong" } = {};
        console.log(msg);
        // "Something went wrong"
        var { x = 3 } = {};
        console.log(x);
        // 3
      
    • 解构用法

        //作为参数
        function removeBreakpoint({ url, line, column }) {
        // ...
        }
      
        //用于迭代
        var map = new Map();
        map.set(window, "the global");
        map.set(document, "the document");
        for (var [key, value] of map) {
        console.log(key + " is " + value);
        }
        // "[object Window] is the global"
        // "[object HTMLDocument] is the document"
      
      
        for (var [,value] of map) {
        // ...
        }
      
        //多值返回
        function returnMultipleValues() {
        return {
                foo: 1,
                bar: 2
        };
        }
        var { foo, bar } = returnMultipleValues();
      

    Arrow Functions(lambda表达式)

    在HTML中-->之前的字符是注释的一部分,而在JS中-->之后的部分才是注释(行首时会注释单行,行中时是趋向于运算符)
    lambda中没有arguments

        // ES5
        var total = values.reduce(function (a, b) {
          return a + b;
        }, 0);
        // ES6
        var total = values.reduce((a, b) => a + b, 0);
    
        // ES6
        $("#confetti-btn").click(event => {
          playTrumpet();
          fireConfettiCannon();
        });
        
        var chewToys = puppies.map(puppy => {});   // 这样写会报Bug!
        var chewToys = puppies.map(puppy => ({})); //
    
        puppy => {}//返回undefined,大括号代表方法体
    

    this

        {
           ...
                addAll: function addAll(pieces) {
                        var self = this;//this指向调用者,方法是调用者的一个属性
                        _.each(pieces, function (piece) {//内层函数里,this会是window或undefined,只能通过以下方法传递this
                          self.add(piece);//把调用者传给内层函数或.bind(this)
                        });
                },
           ...
        }      
          
          
        // ES6
        {
            ...
                addAll: function addAll(pieces) {
                   _.each(pieces, piece => this.add(piece));//lambda中的this可以继承外部函数中的this
                },
            ...
        }      
    

    Symbols

    js中的6种原始类型undefined,null,boolean,number,string,object
    symbols是第7种类型,可以用做属性键避免冲突,它的值与其他任何值都不相等,不能被类似obj.name的点号法访问,被创建后不可改变,当前作用域

        var mySymbol = Symbol();
        obj[mySymbol] = "ok!";  // 保证不会冲突
        console.log(obj[mySymbol]);  // ok!
    
        // 创建一个独一无二的symbol
        var isMoving = Symbol("isMoving");
        ...
        if (element[isMoving]) {
          smoothAnimations(element);
        }
        element[isMoving] = true;
    

    symbols属性的操作

        //属性是否存在
        if (isMoving in element)    
        //删除属性  
        delete element[isMoving]
     
        //会跳过symbols属性
        Object.getOwnPropertyNames(obj)   
        Object.keys(obj)   
        
        //得到symbols属性
        Object.getOwnPropertySymbols(obj)
        
        //不能被隐式转换为string,必须显示转换
        String(sym)
        sym.toString()
    

    创建symbols

        //每次返回新的symbol
        Symbol()
        //共享symbol
        Symbol.for(string)
        //Symbol.iterator
        myArray[Symbol.iterator]
    

    转译器Babel,Broccoli

    数据结构

    set(不包含相同元素,无索引支持,通过数组构建set可以去重)

        let s = new Set()
        s.add('hello').add('world').add('hello')
        console.log(s.size) //=> 2
        console.log(s.has('hello')) //=> true
    
    
        > // 检查"zythum"是不是一个单词
        > arrayOfWords.indexOf("zythum") !== -1  // 慢
                true
        > setOfWords.has("zythum")               // 快
                true
    

    new Set:创建一个新的、空的Set。
    new Set(iterable):从任何可遍历数据中提取元素,构造出一个新的集合。
    set.size:获取集合的大小,即其中元素的个数。
    set.has(value):判定集合中是否含有指定元素,返回一个布尔值。
    set.add(value):添加元素。如果与已有重复,则不产生效果。
    set.delete(value):删除元素。如果并不存在,则不产生效果。.add()和.delete()都会返回集合自身,所以我们可以用链式语法。
    setSymbol.iterator:返回一个新的遍历整个集合的迭代器。一般这个方法不会被直接调用,因为实际上就是它使集合能够被遍历,也就是说,我们可以直接写for (v of set) {...}等等。
    set.forEach(f):直接用代码来解释好了,它就像是for (let value of set) { f(value, value, set); }的简写,类似于数组的.forEach()方法。
    set.clear():清空集合。
    set.keys()、set.values()和set.entries()返回各种迭代器,它们是为了兼容Map而提供的,所以我们待会儿再来看。

    WeakSet

    只能加入对象,如果对象的其他引用已经删除,则对象会从WeakSet中删除

        let weaks = new WeakSet()
        weaks.add("hello") //=> Error
        weaks.add(3.1415) //=> Error
    
        let foo = new String("bar")
        let pi = new Number(3.1415)
        weaks.add(foo)
        weaks.add(pi)
        weaks.has(foo) //=> true
        foo = null
        weaks.has(foo) //=> false
    

    map

    • 避免与内置方法冲突

    • 数据不会作为属性暴露出来,obj.key,obj[key]不能再访问数据了,可以用map.get(key)访问数据

    • 对象可以作为属性

      new Map:返回一个新的、空的Map。
      new Map(pairs):根据所含元素形如[key, value]的数组pairs来创建一个新的Map。这里提供的pairs可以是一个已有的Map 对象,可以是一个由二元数组组成的数组,也可以是逐个生成二元数组的一个生成器,等等。
      map.size:返回Map中项目的个数。
      map.has(key):测试一个键名是否存在,类似key in obj。
      map.get(key):返回一个键名对应的值,若键名不存在则返回undefined,类似obj[key]。
      map.set(key, value):添加一对新的键值对,如果键名已存在就覆盖。
      map.delete(key):按键名删除一项,类似delete obj[key]。
      map.clear():清空Map。
      mapSymbol.iterator:返回遍历所有项的迭代器,每项用一个键和值组成的二元数组表示。
      map.forEach(f) 类似for (let [key, value] of map) { f(value, key, map); }。这里诡异的参数顺序,和Set中一样,是对应着Array.prototype.forEach()。
      map.keys():返回遍历所有键的迭代器。
      map.values():返回遍历所有值的迭代器。
      map.entries():返回遍历所有项的迭代器,就像mapSymbol.iterator。实际上,它们就是同一个方法,不同名字。

    WeakMap

    会检查key,value只有其一的引用被删除,就会从WeakMap中删除

    WeakMap,WeakSet(方便垃圾收集)

        //set是强引用,element作为key,如果element被从dom中移除了,无法回收他的内存,除非在set中也删除
        //WeakSet并不对其中对象保持强引用。当WeakSet中的一个对象被回收时,它会简单地被从WeakSet中移除
        if (movingSet.has(element)) {
          smoothAnimations(element);
        }
          movingSet.add(element);
    

    WeakMap只支持new、has、get、set 和delete。
    WeakSet只支持new、has、add和delete。
    WeakSet的值和WeakMap的键必须是对象。

    Class

        class Person {
        constructor(name, gender, age) {
        this.name = name
        this.gender = gender
        this.age = age
        }
        
        isAdult() {
        return this.age >= 18
        }
        }
        
        let me = new Person('iwillwen', 'man', 19)
        console.log(me.isAdult()) //=> true
    

    继承

        class Animal {
          yell() {
            console.log('yell')
          }
        }
        
        class Person extends Animal {
          constructor(name, gender, age) {
            super() // must call `super` before using `this` if this class has a superclass
    
            this.name = name
            this.gender = gender
            this.age = age
          }
    
          isAdult() {
            return this.age >= 18
          }
        }
        
        class Man extends Person {
          constructor(name, age) {
            super(name, 'man', age)
          }
        }
        
        let me = new Man('iwillwen', 19)
        console.log(me.isAdult()) //=> true
        me.yell()
    

    静态方法

        class Man {
          // ...
    
          static isMan(obj) {
            return obj instanceof Man
          }
        }
        
        let me = new Man()
        console.log(Man.isMan(me)) //=> true
    

    模块

    全局引用

        mport name from 'module-name'
        import * as name from 'module-name'
    

    局部引用

        import { A, B, C } from 'module-name'
        
        A()
        B()
        C()
    

    暴露接口

        // module.js
        export function method() { /* ... */ }
        
        // main.js
        import M from './module'
        M.method()
    
        //覆盖暴露
        // module.js
        export default {
          method1,
          method2
        }
        
        // main.js
        import M from './module'
        M.method1()
    

    Promise

        function fetchData() {
          return new Promise((resolve, reject) => {
            api.call('fetch_data', (err, data) => {
              if (err) return reject(err)
      
              resolve(data)
            })
          })
        }
    
        fetchData()
          .then(data => {
            // ...
    
            return storeInFileSystem(data)
          })
          .then(data => {
            return renderUIAnimated(data)
          })
          .catch(err => console.error(err))
    

    Proxy

    不修改目标的前提下,拦截逻辑进行处理

        let apiProxy = new Proxy(api, {
          get(receiver, name) {
            return (function(...args) {
              min.sadd(`log:${name}`, args)
              return receiver[name].apply(receiver, args)
            }).bind(receiver)
          }
        })
        
        api.getComments(artical.id)
          .then(comments => {
            // ...
          })
    

    深入浅出ES6
    给 JavaScript 初心者的 ES2015 实战

  • 相关阅读:
    linux下文件夹的创建、复制、剪切、重命名、清空和删除命令
    Linux 删除文件夹和创建文件的命令
    linux下拷贝整个目录
    星云大师:这十句话 我受用一生
    dex
    瘋耔java语言笔记
    VCC_VID_VTT等的含义
    一位数码管引脚
    android从应用到驱动之—camera(2)---cameraHAL的实现
    android从应用到驱动之—camera(1)---程序调用流程[转]
  • 原文地址:https://www.cnblogs.com/yfann/p/4848547.html
Copyright © 2011-2022 走看看