美文网首页Devs
ECMAScript 6 (ES6) 新特性介绍 四

ECMAScript 6 (ES6) 新特性介绍 四

作者: 乌龟怕铁锤 | 来源:发表于2017-12-15 12:02 被阅读7次

    原文地址 ECMAScript 6 — New Features: Overview & Comparison
    本文介绍 ECMAScript 6中的新特性并通过具体代码演示与ECMAScript 5的差别。译者额外增加了一些例子和说明 .

    ECMAScript 6 是2015年推出的第6版本的ECMAScript标准(即Javascript标准),同时也被成为ECMAScript 2015.

    ECMAScript 6 中定了了许多新的Javascript特性,包括新的类和模块,类似python的generators和generators表达式, 箭头函数, 二进制数据, 类型数组, 集合类型(maps, set & 弱maps), promises, reflection, proxy等。它也被称作 ES6 Harmony. (和谐ES6)

    本文是该系列文章的第四篇

    新内建方法

    对象属性的赋值

    新的assign函数可以枚举属性并指定一个或者多个对象映射到目标对象中

    ECMAScript 6的实现

    var dest = { quux: 0 }
    var src1 = { foo: 1, bar: 2 }
    var src2 = { foo: 3, baz: 4 }
    Object.assign(dest, src1, src2) // assign src1, src2的属性到 dest对象中
    dest.quux === 0
    dest.foo  === 3
    dest.bar  === 2
    dest.baz  === 4
    

    对比ECMAScript 5的实现

    var dest = { quux: 0 };
    var src1 = { foo: 1, bar: 2 };
    var src2 = { foo: 3, baz: 4 };
    Object.keys(src1).forEach(function(k) { // 需要遍历key并取值赋值
        dest[k] = src1[k];
    });
    Object.keys(src2).forEach(function(k) {
        dest[k] = src2[k];
    });
    dest.quux === 0;
    dest.foo  === 3;
    dest.bar  === 2;
    dest.baz  === 4;
    

    数组元素的寻找

    新的方法用来寻找数组中的元素
    ECMAScript 6的实现

    // 这个find/findIndex函数只寻找返回满足条件的第一个元素
    [ 1, 3, 4, 2 ].find(x => x > 3) // 4
    [ 1, 3, 4, 2 ].findIndex(x => x > 3) // 2 
    

    对比ECMAScript 5的实现

    [ 1, 3, 4, 2 ].filter(function (x) { return x > 3; })[0]; // 4
    //  ES5中无findIndex
    

    字符串重复

    新的repeat方法来重复字符串

    ECMAScript 6的实现

    " ".repeat(4 * depth)
    "foo".repeat(3)
    

    对比ECMAScript 5的实现

    Array((4 * depth) + 1).join(" ");
    Array(3 + 1).join("foo");
    

    字符串查找

    新的statsWith endsWith和includes 方法用来查找字符串
    ECMAScript 6的实现

    "hello".startsWith("ello", 1) // true
    "hello".endsWith("hell", 4)   // true
    "hello".includes("ell")       // true
    "hello".includes("ell", 1)    // true
    "hello".includes("ell", 2)    // false
    

    对比ECMAScript 5的实现

    "hello".indexOf("ello") === 1;    // true
    "hello".indexOf("hell") === (4 - "hell".length); // true
    "hello".indexOf("ell") !== -1;    // true
    "hello".indexOf("ell", 1) !== -1; // true
    "hello".indexOf("ell", 2) !== -1; // false
    

    数值类型检查

    检查是否为NaN和无穷数值
    ECMAScript 6的实现

    Number.isNaN(42) === false
    Number.isNaN(NaN) === true
    
    Number.isFinite(Infinity) === false
    Number.isFinite(-Infinity) === false
    Number.isFinite(NaN) === false
    Number.isFinite(123) === true
    

    对比ECMAScript 5的实现

    var isNaN = function (n) {
        return n !== n;
    };
    var isFinite = function (v) {
        return (typeof v === "number" && !isNaN(v) && v !== Infinity && v !== -Infinity);
    };
    isNaN(42) === false;
    isNaN(NaN) === true;
    
    isFinite(Infinity) === false;
    isFinite(-Infinity) === false;
    isFinite(NaN) === false;
    isFinite(123) === true;
    

    数值的安全检查

    检查一个数字的值是否在安全的范围内, 例如能够正确的以javascript展示(其实说有的数值,包括integer数值,都是浮点数值)

    ECMAScript 6的实现

    Number.isSafeInteger(42) === true
    Number.isSafeInteger(9007199254740992) === false
    

    对比ECMAScript 5的实现

    function isSafeInteger (n) {
        return (
               typeof n === 'number'
            && Math.round(n) === n
            && -(Math.pow(2, 53) - 1) <= n
            && n <= (Math.pow(2, 53) - 1)
        );
    }
    isSafeInteger(42) === true;
    isSafeInteger(9007199254740992) === false;
    

    数值的比较

    提供了标准的 Epsilon (临界值),用来作为浮点数直接的比较依据。

    ECMAScript 6的实现

    console.log(0.1 + 0.2 === 0.3) // false
    console.log(Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON) // true
    

    对比ECMAScript 5的实现

    console.log(0.1 + 0.2 === 0.3); // false
    console.log(Math.abs((0.1 + 0.2) - 0.3) < 2.220446049250313e-16); // true
    

    数值截断

    讲浮点(float)数截断为整型(integer)数值, 这里的截断是完全去掉小数点后的值
    ECMAScript 6的实现

    console.log(Math.trunc(42.7)) // 42
    console.log(Math.trunc( 0.1)) // 0
    console.log(Math.trunc(-0.1)) // -0
    

    对比ECMAScript 5的实现

    function mathTrunc (x) {
        return (x < 0 ? Math.ceil(x) : Math.floor(x));
    }
    console.log(mathTrunc(42.7)) // 42
    console.log(mathTrunc( 0.1)) // 0
    console.log(mathTrunc(-0.1)) // -0
    

    数值符号选定

    确定一个数值的符号, 包括带符号0和非数值.

    ECMAScript 6的实现

    console.log(Math.sign(7))   // 1
    console.log(Math.sign(0))   // 0
    console.log(Math.sign(-0))  // -0
    console.log(Math.sign(-7))  // -1
    console.log(Math.sign(NaN)) // NaN
    

    对比ECMAScript 5的实现

    function mathSign (x) {
        return ((x === 0 || isNaN(x)) ? x : (x > 0 ? 1 : -1));
    }
    console.log(mathSign(7))   // 1
    console.log(mathSign(0))   // 0
    console.log(mathSign(-0))  // -0
    console.log(mathSign(-7))  // -1
    console.log(mathSign(NaN)) // NaN
    

    Promise

    Promise的使用

    首先是关于如果表述一个异步在未来可以获取到的值的表达式. 更多Promise的信息.
    ECMAScript 6的实现

    function msgAfterTimeout (msg, who, timeout) {
        return new Promise((resolve, reject) => { // 返回的promise, 会异步,在未来的某个时间调用resolve来完成
            setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout)
        })
    }
    msgAfterTimeout("", "Foo", 100).then((msg) => //  对于完成的promise需要通过then来继续实现
        msgAfterTimeout(msg, "Bar", 200)
    ).then((msg) => {
        console.log(`done after 300ms:${msg}`)
    })
    

    对比ECMAScript 5的实现

    function msgAfterTimeout (msg, who, timeout, onDone) {
        setTimeout(function () {
            onDone(msg + " Hello " + who + "!");
        }, timeout);
    }
    msgAfterTimeout("", "Foo", 100, function (msg) {
        msgAfterTimeout(msg, "Bar", 200, function (msg) {
            console.log("done after 300ms:" + msg);
        });
    });
    

    Promise的联合

    同时也可以把多个promise联合到一个新的promise, 等待他们的完成,无需关心他们的中间执行顺序。

    ECMAScript 6的实现

    function fetchAsync (url, timeout, onData, onError) {
        …
    }
    let fetchPromised = (url, timeout) => {
        return new Promise((resolve, reject) => {
            fetchAsync(url, timeout, resolve, reject)
        })
    }
    Promise.all([
        fetchPromised("http://backend/foo.txt", 500),
        fetchPromised("http://backend/bar.txt", 500),
        fetchPromised("http://backend/baz.txt", 500)
    ]).then((data) => {
        let [ foo, bar, baz ] = data // 返回的数值是按照promise排列的顺序执行
        console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
    }, (err) => {
        console.log(`error: ${err}`)
    })
    

    对比ECMAScript 5的实现

    function fetchAsync (url, timeout, onData, onError) {
        …
    }
    function fetchAll (request, onData, onError) {
        var result = [], results = 0;
        for (var i = 0; i < request.length; i++) {
            result[i] = null;
            (function (i) {
                fetchAsync(request[i].url, request[i].timeout, function (data) {
                    result[i] = data;
                    if (++results === request.length)
                        onData(result);
                }, onError);
            })(i);
        }
    }
    fetchAll([
        { url: "http://backend/foo.txt", timeout: 500 },
        { url: "http://backend/bar.txt", timeout: 500 },
        { url: "http://backend/baz.txt", timeout: 500 }
    ], function (data) {
        var foo = data[0], bar = data[1], baz = data[2];
        console.log("success: foo=" + foo + " bar=" + bar + " baz=" + baz);
    }, function (err) {
        console.log("error: " + err);
    });
    

    元程序

    Proxying

    Proxy能够嵌入运行时对象的元操作.

    ECMAScript 6的实现

    let target = {
        foo: "Welcome, foo"
    }
    let proxy = new Proxy(target, { // 定义了一个针对对象的proxy, 重定义了get元操作.
        get (receiver, name) {
            return name in receiver ? receiver[name] : `Hello, ${name}`
        }
    })
    proxy.foo   === "Welcome, foo"
    proxy.world === "Hello, world"
    

    对比ECMAScript 5的实现

    // ES5中无
    

    Reflection

    针对Object的一系列操作,和之前的Object.方法不同的是,reflection的返回值是有意义的。
    Reflection提供了一系列的操作方法,这里的例子中只有一个,更详细的请看这里 - 译者会跟进翻译这篇文章。

    ECMAScript 6的实现

    let obj = { a: 1 }
    Object.defineProperty(obj, "b", { value: 2 })
    obj[Symbol("c")] = 3
    Reflect.ownKeys(obj) // [ "a", "b", Symbol(c) ] // 这里只介绍了ownKeys这个方法 
    

    对比ECMAScript 5的实现

    var obj = { a: 1 };
    Object.defineProperty(obj, "b", { value: 2 });
    // no equivalent in ES5
    Object.getOwnPropertyNames(obj); // [ "a", "b" ]
    

    相关文章

      网友评论

        本文标题:ECMAScript 6 (ES6) 新特性介绍 四

        本文链接:https://www.haomeiwen.com/subject/hzvrwxtx.html