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

  • 相关阅读:
    工作中遇到的java 内存溢出,问题排查
    java线上内存溢出问题排查步骤
    性能测试-java内存溢出问题排查
    164 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 04 终止finally执行的方法
    163 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 03 使用多重catch结构处理异常
    162 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 02 使用try-catch结构处理异常
    161 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 01 try-catch-finally简介
    160 01 Android 零基础入门 03 Java常用工具类01 Java异常 03 异常处理简介 01 异常处理分类
    159 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 02 异常分类
    158 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 01 什么是异常?
  • 原文地址:https://www.cnblogs.com/diydyq/p/4190214.html
Copyright © 2011-2022 走看看