zoukankan      html  css  js  c++  java
  • JS篇 ES6新特性

    注意:

    1. Node环境下,--harmony参数启用ES6新特性,这些新特性只有在strict mode下才生效,因此使用"use strict"或者--use_strict,否则harmony没有被启用;

    2. Extended Mode: 当启用新特性的时候,context处于extended mode下;而且这些feature仅仅只在strict mode下有效;

    1. let与const:

      1. 块级作用域(Block scope

      2. let声明

      3. const声明

    // Block scope
    function f1(){
        console.log("Outside.");
    }
    (function(){
        if(false){
         // f1定义在if {}之内
    function f1() { console.log("Inside."); } } f1(); }());

      ES5中:

      1. strict mode:     将会报错:In strict mode code, functions can only be declared at top level or immediately within another function.(函数只能声明在Glocal scope或者函数里的最外层)

      2. non-strict mode:    输出:"Inside";

      ES6中:

      1. strict mode:     输出:"Outside",(node环境下使用命令:node --harmony --use_strict 1_blockScope.js,使用node 1_blockScope.js --harmony命令,harmony没有起作用)

      2. non-strict mode:  输出:"Inside";(根据上面第一条:non-strict mode下不启用harmony)

      因为ES6中,出现了块级作用域,导致上面的代码在ES6 context的strict mode中是有意义的;

      let声明的变量,其作用域仅在块级作用域之内

    {
        let a = 1;
        var b = 2;
    }
    a
    b
    // ES6下:ReferenceError: a is not defined
    // ES5下:SyntaxError: Illegal let declaration outside extended mode

      因为let不会有变量提升,所以输出v1=5, i=10;个人感觉:之前共用函数作用域,现在增加了块级作用域不会增加内存占用吗?

    function f1(){
        var list = [];
        for(var i=0; i<10; i++){
            let v1 = i;
            list.push(function(){
               console.log(v1, i);
            });
        }
        list[5]();  // output: 5 10
    }
    f1();

      IIFE的目的是说:定义的变量存在于函数作用域中,不在最外层Global,避免对Global的污染;基于这一目的,可以使用块级作用域来代替IIFE;

      定义常量,node环境下,重新赋值报错:SyntaxError: Assignment to constant variable.

    const PI = 3.14;
    // SyntaxError: Assignment to constant variable.
    //console.log(PI=3.13);
    console.log(PI);

         

    4. Destructing析构赋值

      下面列出了析构的几个常用之处:1. 函数传参;2. 函数返回;3. 函数参数默认值;4. for..of遍历

    // 1. Passing arguments
    function f1({x, y}){
        console.log(arguments);
    }
    f1({x:"Hello", y:"Function"});
    
    
    // 2. Accept function returns
    var f1Ret = (function(){
        return {x: "hello", y:"function"};
    })();
    console.log(f1Ret);
    
    
    // 3.Passing arguments with fixed arguments
    function f1({x="hello", y="world"}){
        console.log(arguments);
    }
    f1({x:"Hi", y:"Function"});
    
    
    // 4. for...of
    var m1 = new Map();
    m1.set("Hello", "World");
    m1.set("Hi", "Map");
    
    for(let [k, v] of m1){
        console.log(k, v);
    }

    5. Number扩展:

      1. Number.isFinite()

      2. Number.isNaN()

      3. Number.isInteger()

    "use strict";
    
    /**
     * Number:
     * 1. Number.isFinite(), Number.isNaN()
     * 2. Number.isInteger
     *
     */
    
    console.log("isFinite: ", Number.isFinite(Infinity), Number.isFinite(-Infinity), Number.isFinite(0));
    
    console.log("isNaN: ", Number.isNaN(NaN));
    
    //console.log("parseInt: ", Number.parseInt("13.00"));
    
    console.log(Number.isInteger(3.01));

    6. 数组扩展:

    1. Array.from(...)   抽取Array-like对象或者Interable对象
    2. Array.of(...)     将零散值转换为数组
    3. array.fill()      填充
    4. find(fn), findIndex(fn)
    "use strict";
    
    /**
     * Array:
     * 1. Array.from(...)   抽取Array-like对象或者Interable对象
     * 2. Array.of(...)     将零散值转换为数组
     * 3. array.fill()      填充
     * 4. find(fn), findIndex(fn)
     * 5. Array.observe()   监听
     */
    
    var m1 = new Map();
    m1.set("A").set("B");
    
    var a1 = Array.from(m1);
    console.log(a1);
    
    console.log(Array.of(10, 20, 30));
    
    console.log([null, null].fill(10));
    
    var a2 = [10, 20];
    console.log(a2.find(function (v, i) {
        return v == 10;
    }), a2.findIndex(function (v, i) {
        return v == 10;
    }));

    7. 对象扩展:

      1. Object.is

      2. Object.assign

      3. Object.getPrototype

      4. Object.setPrototypeOf

    /**
     * Object.is(o1, o2)    判断对象是否相等
     * Object.assign(target, src1, src2)
     * Object.getPrototype(obj)
     * Object.setPrototypeOf(o1, o2)
     * 将对象、方法直接写入对象
     */
    
    
    console.log("Object.is(+0, -0): ", Object.is(+0, -0), +0 === -0);
    console.log("Object.is(NaN, NaN): ", Object.is(NaN, NaN), NaN === NaN);
    
    var o1 = { a1: "1st" };
    var o2 = { a1: "2nd" };
    var o3 = { a1: "3rd" };
    console.log(Object.assign(o1, o2, o3));
    
    console.log(Object.getPrototypeOf(o1) === Object.prototype);
    //console.log(Object.setPrototypeOf({}, o1).a1);
    
    var username = "diydyq";
    var eat = new Function;
    var o4 = {
        username,
        eat,
        o1,
        [username]: username 
    };
    // { username: 'diydyq', eat: [Function], o1: { a1: '3rd' } }
    console.log(o4);

    8. 函数扩展:

      1. 参数默认值

      2. Rest参数(将一系列实参映射到形参数组

      3. 扩展运算符(将数组实参映射到一系列逗号分隔的形参

      4. 箭头函数(this不可更改,arguments指向的不是自身的参数)

    "use strict";
    var l1 = [10, 20];
    
    /**
     * 参数默认值
     */
    var f1 = function (x="default argument") {
        console.log(x);
    };
    f1();
    f1("specified argument");
    
    
    /**
     * Rest参数:
     * 1. 将一系列实参转换为数组
     */
    var f2 = function (name, ...left) {
        console.log(name, left, left instanceof Array);
    };
    f2("s1", "s2", "s3");
    
    /**
     * 扩展运算符(spread)
     * 1. 将数组实参转换为一系列的形参
     */
    var v3 = [10, 20, 30];
    var f3 = function (v1) {
        console.log(v1, arguments);
    };
    f3(...v3);
    
    Math.max.apply(null, v3);
    Math.max(...v3);
    
    
    /**
     * 箭头函数
     * 1. this 绑定了定义时的对象,call|apply却无法更改,为什么不应该呢?
     * 2. arguments变量可以使用,但不是该函数对应的参数,而是包含它的函数的参数
     */
    var f1 = v => { console.log(v); };
    l1.forEach(f1);
    
    function f2Wrap(){
        var f2 = (v) => { console.log(this == global, arguments, v == arguments[0], v && Object.prototype.valueOf.call(v)); };
        f2();
        f2(l1);
        f2.call(l1, l1);
    }
    
    f2Wrap("Test");

    9. Set与Map操作:

      1. Set:不可重复的数组,可用于数组去重(属性:size;5个方法:set() get() has() delete() clear())

      2. Map: 存放的键名key不限于简单数据类型,支持对象作为键(属性:size;5个方法:set() get() has() delete() clear(),遍历:keys() values() entries())

      3. WeakMap: Traceur中暂不支持(TODO:待使用);

    "use strict";
    var l1 = [10, 20, 30, 20];
    var s1 = new Set(l1);
    
    /**
     * Set对象:
     * 1. 1个属性: size
     * 2. 4个方法:add() delete() has() clear()
     */
    console.log(s1, s1.size);
    console.log(s1, s1.add(100).delete(10), s1.has(100), s1.size);
    console.log(s1.map_);
    
    console.log("-------------------------------------------------");
    
    /**
     * Map对象:
     * 1. 1个属性:size
     * 2. 多个属性:set(), get(), has(), delete(), clear()
     * 3. m.set(k, v) 不同于 m[k] = v; 后者是给这个m对象赋值;
     */
    var m1 = new Map();
    var o1 = { attr1: "Test" };
    var o2 = [10, 20];
    
    m1[o1] = "Value for o1";
    m1.set(o1, "Value for o1 new1");
    m1.set(o2, "ValueFor o2");
    
    console.log(m1, m1[o1], m1.get(o1), m1.has(o1), m1.delete({}));
    console.log(m1);
    m1.clear();
    
    m1[0] = "Value for 0";
    m1.set(0, "Value, for 0 new1");
    console.log(m1[0], m1.get(0), m1, m1.size);
    
    
    for(let k of m1.keys()){
        console.log(k);
    }
    for(let v of m1.values()){
        console.log(v);
    }
    for(let [k, v] of m1.entries()){
        console.log(k, v);
    }
    
    /**
     * WeakMap对象:
     * TODO:traceur中找不到
     *
     */
    //var wm1 = new WeakMap();
    //wm1.set(o1, "Value for o1");
    //wm1.set(o2, "Value for o2");
    //console.log(wm1.size);

    11 Generator函数:

      1. 每次yield或者return返回新的对象:{ value: ..., done: false|true }  
      2. return后再次调用next()返回空的value对象: { value: undefined, done: true }
      3. next()传参:
        1) 第一次next传递参数,会报错:ModuleEvaluationError: Sent value to newborn generator
        2) 所以如果第一次需要传参,可以在生成generator时添加;
        3) 后续的next参数,将作为yield表达式的返回值

    "use strict";
    
    /**
     * Generator:
     * 1. 每次yield或者return返回新的对象:{ value: ..., done: false|true }
     * 2. return后再次调用next()返回空的value对象: { value: undefined, done: true }
     * 3. next()传参:
     *    1) 第一次next传递参数,会报错:ModuleEvaluationError: Sent value to newborn generator
     *    2) 所以如果第一次需要传参,可以在生成generator时添加;
     *    3) 后续的next参数,将作为yield表达式的返回值
     */
    function* generatorFrom1(arg1){
        console.log("Execute generator: ", arg1);
        var o1 = {};
        for(var i=0; i<2; i++){
            o1.idx = i;
            var yRet = yield o1;
            console.log("yield Return: ", yRet);
        }
        return o1;
    }
    
    var g1 = new generatorFrom1(), g2 = new generatorFrom1("First time execution.");
    var r1, r2;
    
    r1 = g1.next();
    r2 = g1.next();
    console.log(r1, r2, r1 == r2);
    console.log(g1.next(), g1.next());
    
    console.log("----------------------------------");
    console.log("Execute 1: start");
    r1 = g2.next();
    console.log("Execute 1: end");
    
    console.log("Execute 2: start");
    r2 = g2.next("argument Test");
    console.log("Execute 2: end");
    console.log(r1, r2);

    12 Promise:

      1. Promise的构造函数必须为function,否则TypeError;

      2. catch(fn)用于处理reject的信息;

      3. 如果让下一个执行resolve,则return;否则拒绝的话,使用throw new Error()

      4. Promise.all()参数是一个数组,不是零散的promise对象

    "use strict";
    
    /**
     * Promise:
     * 1. Promise的构造函数必须为function,否则TypeError;
     * 2. catch(fn)用于处理reject的信息;
     * 3. 如果让下一个执行resolve,则return;否则拒绝的话,使用throw new Error()
     * 4. Promise.all()参数是一个数组,不是零散的promise对象
     * 5. async功能未成功试用
     */
    
    var fn1 = function(resolve, reject){
        setTimeout(function () {
            console.log("Execute promise function");
            resolve("Resoved Message");
            //reject("Rejected Message");
        }, 1000);
    };
    
    //var p1 = new Promise(fn1);
    var p1 = new Promise(fn1);
    
    p1.then(function (msg) {
        console.log("1st resolve: ", arguments);
    }, function (msg) {
        console.log("1st reject: ", arguments);
        //return "1st pass to 2nd message";
        throw new Error(["1st pass rejected message"]);
    }).then(function (msg) {
        console.log("2st resolve: ", arguments);
    }, function (msg) {
        console.log("2st reject: ", arguments);
    }).catch(function (msg) {
        console.warn("3rd reject: ", arguments);
    });
    
    
    var fn2 = function(resolve, reject){
        setTimeout(function () {
            console.log("Execute promise function");
            resolve("Resoved Message");
            //reject("Rejected Message");
        }, 500);
    };
    var p2 = new Promise(fn2);
    
    
    var pAll1 = Promise.all([p1, p2]).then(function (msg) {
        console.log("1st resolve: ", arguments);
    }, function (msg) {
        console.log("1st reject: ", arguments);
    });
    
    console.log("-----------------------------------");
    //async function asyncFn1() {
    //    console.log("Async before");
    //    let ret1 = await (function () {
    //        return new Promise(fn1);
    //    })();
    //    console.log("Async After");
    //}
    //asyncFn1();

    参考:

    1. ruanyifeng       http://es6.ruanyifeng.com/#docs/let

    2. Stackoverflow    http://stackoverflow.com/questions/17253509/what-is-extended-mode

  • 相关阅读:
    echars 折线图使用
    echars 饼图使用
    React native中DrawerNavigator,StackNavigator,TabNavigator导航栏使用
    React native 中 SectionList用法
    React native 中使用Fetch请求数据
    React native中使用XMLHttpRequest请求数据
    实现在WebView中返回上一级
    DatePickerAndroid用法
    Lambda
    .Net常见线程安全问题整理
  • 原文地址:https://www.cnblogs.com/diydyq/p/4190214.html
Copyright © 2011-2022 走看看