美文网首页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