es6 新特性整理
来源:互联网 发布:幼儿教师网络研修计划 编辑:程序博客网 时间:2024/06/06 20:13
本文没有详细描述这些新特性,因为网上都已经有很多相关的介绍了。主要针对ES6 新特性收集了相关范例代码,他可以让你快速了解这个新的javascript规范。
箭头函数
function() 函数的简写表示法,但它不绑定 this。
ES6 代码:
var odds = evens.map(v => v + 1); // no parentes and no bracketsvar nums = evens.map((v, i) => v + i);var pairs = evens.map(v => ({even: v, odd: v + 1})); // Statement bodiesnums.forEach(v => { if (v % 5 === 0) fives.push(v);});
this 是如何工作的?
ES6 代码:
var object = { name: "Name", arrowGetName: () => this.name, regularGetName: function() { return this.name }, arrowGetThis: () => this, regularGetThis: function() { return this }}console.log(object);console.log(object.name)console.log(object.arrowGetName());console.log(object.arrowGetThis());console.log(this);console.log(object.regularGetName());console.log(object.regularGetThis());
结果:
console.log(object); =>Object { name: "Name", arrowGetName: function, regularGetName: function, arrowGetThis: function, regularGetThis: function}console.log(object.name) => Nameconsole.log(object.arrowGetName()); =>undefinedconsole.log(object.arrowGetThis()); => [object Window] Window { stop: function, open: function, alert: function, confirm: function, prompt: function, ...}console.log(this); => 同上console.log(object.regularGetName()); =>Nameconsole.log(object.regularGetThis()); =>Object { name: "Name", arrowGetName: function, regularGetName: function, arrowGetThis: function, regularGetThis: function}
我们知道“真正”语言中的类(Classes)。在 ES6 中类(Classes)其实是原型继承的语法糖。
ES6 代码:
class SkinnedMesh extends THREE.Mesh { constructor(geometry, materials) { super(geometry, materials); this.idMatrix = SkinnedMesh.defaultMatrix(); this.bones = []; this.boneMatrices = []; //... } update(camera) { //... super.update(); } get boneCount() { return this.bones.length; } set matrixType(matrixType) { this.idMatrix = SkinnedMesh[matrixType](); } static defaultMatrix() { return new THREE.Matrix4(); }}
增强的对象字面量
ES6 代码:
var theProtoObj = { toString: function() { return "The ProtoOBject To string" }}var handler = () => "handler"var obj = { // __proto__ __proto__: theProtoObj, // Shorthand for ‘handler: handler’ handler, // Methods toString() { // Super calls return "d " + super.toString(); }, // Computed (dynamic) property names [ "prop_" + (() => 42)() ]: 42}; console.log(obj.handler)console.log(obj.handler())console.log(obj.toString())console.log(obj.prop_42)
结果:
obj.handler -> () => "handler"obj.handler() -> handlerobj.toString() -> d The ProtoOBject To stringobj.prop_42 -> (() => 42)() 是一个立即执行函数 (() => 42)() 相当于(function() { return 42;})()42
字符串插值
var name = "Bob", time = "today"; var multiLine = `This Line Spans Multiple Lines`; console.log(`Hello ${name},how are you ${time}?`)console.log(multiLine)
结果:
`Hello ${name},how are you ${time}?` -> Hello Bob,how are you today?multiLine -> This Line Spans Multiple Lines
解构 Destructuring
// list "matching"var [a, , b] = [1,2,3];console.log(a);console.log(b);
结果:
a -> 1b -> 3
对象也能很好的解构
nodes = () => { return {op: "a", lhs: "b", rhs: "c"}}var { op: a, lhs: b , rhs: c } = nodes()console.log(a)console.log(b)console.log(c)
结果:
a -> ab -> bc -> c
使用速记表示法。
nodes = () => { return {lhs: "a", op: "b", rhs: "c"}} // binds `op`, `lhs` and `rhs` in scopevar {op, lhs, rhs} = nodes() console.log(op)console.log(lhs)console.log(rhs)
结果:
op -> blhs -> arhs -> c
可在参数位置使用
function g({name: x}) { return x} function m({name}) { return name} console.log(g({name: 5}))console.log(m({name: 5}))
结果:
g({name: 5}) -> 5m({name: 5}) -> 5
故障弱化解构
var [a] = []var [b = 1] = []var c = [];console.log(a)console.log(b);console.log(c);
结果:
a -> undefinedb -> 1c -> []
参数默认值(Default)
function f(x, y=12) { return x + y;} console.log(f(3))console.log(f(3,2))
结果:
f(3) -> 15f(3,2) -> 5
扩展(Spread)
在函数中:
function f(x, y, z) { return x + y + z;}// 传递数组的每个元素作为参数console.log(f(...[1,2,3]))
结果:
f(...[1,2,3]) -> 6
在数组中:
var parts = ["shoulders", "knees"];var lyrics = ["head", ...parts, "and", "toes"]; console.log(lyrics)
结果:
lyrics -> ["head","shoulders","knees","and","toes"]
扩展 + 对象字面量
我们可以使用这个创造很酷的对象。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };console.log(x); // 1console.log(y); // 2console.log(z); // { a: 3, b: 4 } // Spread propertieslet n = { x, y, ...z };console.log(n); // { x: 1, y: 2, a: 3, b: 4 }console.log(obj)可惜的是它还不支持:npm install --save-dev babel-plugin-transform-object-rest-spread
Rest
我们可以使用 rest 操作符来允许无限参数。
function demo(part1, ...part2) { return {part1, part2}} console.log(demo(1,2,3,4,5,6))
结果:
demo(1,2,3,4,5,6) -> {"part1":1,"part2":[2,3,4,5,6]}
Let
let是新的var。 因为它有块级作用域。
{ var globalVar = "from demo1"} { let globalLet = "from demo2";} console.log(globalVar)console.log(globalLet)
结果:
globalVar -> from demo1globalLet -> ReferenceError: globalLet is not defined
但是,它不会向window分配任何内容:
let me = "go"; // 全局作用域var i = "able"; // 全局作用域 console.log(window.me); console.log(window.i);
结果:
window.me -> undefinedwindow.i -> able
不能使用let重新声明一个变量:
let me = "foo";let me = "bar"; console.log(me);
结果:
SyntaxError: Identifier 'me' has already been declared
var me = "foo";var me = "bar"; console.log(me)
结果:
me -> bar
Const
const 是只读变量。
const a = "b"a = "a"
结果:
TypeError: Assignment to constant variable.
应该注意,const 对象仍然可以被改变的。
const a = { a: "a" }a.a = "b"console.log(a)
结果:
a -> {"a":"b"}
For..of
迭代器的新类型,可以替代for..in。 它返回的是值而不是keys。
let list = [4, 5, 6];console.log(list)for (let i in list) { console.log(i);}
结果:
list -> [4,5,6]i -> 0i -> 1i -> 2
let list = [4, 5, 6];console.log(list)for (let i of list) { console.log(i); }
结果:
list -> [4,5,6]i -> 4i -> 5i -> 6
迭代器(Iterators)
迭代器是一个比数组更动态的类型。
let infinite = { [Symbol.iterator]() { let c = 0; return { next() { c++; return { done: false, value: c } } } }} console.log("start"); for (var n of infinite) { // truncate the sequence at 1000 if (n > 10) break; console.log(n);}
结果:
"start" -> startn -> 1n -> 2n -> 3n -> 4n -> 5n -> 6n -> 7n -> 8n -> 9n -> 10
使用Typescript,我们可以看到它接口的样子:
Typescript 代码:interface IteratorResult { done: boolean; value: any;}interface Iterator { next(): IteratorResult;}interface Iterable { [Symbol.iterator](): Iterator}
生成器(Generators)
生成器创建迭代器,并且比迭代器更具动态性。他们不必以相同的方式跟踪状态 并不支持 done 的概念。
var infinity = { [Symbol.iterator]: function*() { var c = 1; for (;;) { yield c++; } }} console.log("start")for (var n of infinity) { // truncate the sequence at 1000 if (n > 10) break; console.log(n);}
结果:
"start" -> startn -> 1n -> 2n -> 3n -> 4n -> 5n -> 6n -> 7n -> 8n -> 9n -> 10
使用Typescript 再次显示接口:
Typescript 代码:
interface Generator extends Iterator { next(value?: any): IteratorResult; throw(exception: any);}
function* Iterators and generator
一个产量的例子*
function* anotherGenerator(i) { yield i + 1; yield i + 2; yield i + 3;} function* generator(i) { yield i; yield* anotherGenerator(i); yield i + 10;} var gen = generator(10); console.log(gen.next().value); console.log(gen.next().value); console.log(gen.next().value); console.log(gen.next().value); console.log(gen.next().value);
结果:
gen.next().value -> 10gen.next().value -> 11gen.next().value -> 12gen.next().value -> 13gen.next().value -> 20
Unicode
ES6 为Unicode 提供了更好的支持。
var regex = new RegExp('\u{61}', 'u'); console.log(regex.unicode)console.log("\uD842\uDFD7")console.log("\uD842\uDFD7".codePointAt())
结果:
regex.unicode -> true"" -> "".codePointAt() -> 134103
模块和模块加载器
原生支持模块。
import defaultMember from "module-name";import * as name from "module-name";import { member } from "module-name";import { member as alias } from "module-name";import { member1 , member2 } from "module-name";import { member1 , member2 as alias2 , [...] } from "module-name";import defaultMember, { member [ , [...] ] } from "module-name";import defaultMember, * as name from "module-name";import "module-name";
export { name1, name2, …, nameN };export { variable1 as name1, variable2 as name2, …, nameN };export let name1, name2, …, nameN; // also varexport let name1 = …, name2 = …, …, nameN; // also var, const export expression;export default expression;export default function (…) { … } // also class, function*export default function name1(…) { … } // also class, function*export { name1 as default, … }; export * from …;export { name1, name2, …, nameN } from …;export { import1 as name1, import2 as name2, …, nameN } from …;Import Export
Set
Set 为数学对应,其中所有项目都是唯一的。对于知道SQL的人来说,这相当于distinct。
var set = new Set();set.add("Potato").add("Tomato").add("Tomato");console.log(set.size)console.log(set.has("Tomato")) for(var item of set) { console.log(item)}
结果:
set.size -> 2set.has("Tomato") -> trueitem -> Potatoitem -> Tomato
WeakSet
WeakSet对象允许您在集合中存储弱持有的对象。没有引用的对象将被垃圾回收。
var item = { a:"Potato"}var set = new WeakSet();set.add({ a:"Potato"}).add(item).add({ a:"Tomato"}).add({ a:"Tomato"});console.log(set.size)console.log(set.has({a:"Tomato"}))console.log(set.has(item)) for(let item of set) { console.log(item)}
结果:
set.size -> undefinedset.has({a:"Tomato"}) -> falseset.has(item) -> trueTypeError: set[Symbol.iterator] is not a function
Map
Map 也称为词典。
var map = new Map();map.set("Potato", 12);map.set("Tomato", 34); console.log(map.get("Potato")) for(let item of map) { console.log(item)} for(let item in map) { console.log(item)}
结果:
map.get("Potato") -> 12item -> ["Potato",12]item -> ["Tomato",34]
可以使用除字符串之外的其他类型。
var map = new Map();var key = {a: "a"}map.set(key, 12);console.log(map.get(key))console.log(map.get({a: "a"}))
结果:
map.get(key) -> 12map.get({a: "a"}) -> undefined
WeakMap
使用键的对象,并且只保留对键的弱引用。
var wm = new WeakMap();var o1 = {}var o2 = {}var o3 = {}wm.set(o1, 1);wm.set(o2, 2);wm.set(o3, {a: "a"});wm.set({}, 4); console.log(wm.get(o2));console.log(wm.has({})) delete o2; console.log(wm.get(o3)); for(let item in wm) { console.log(item)} for(let item of wm) { console.log(item)}
结果:
wm.get(o2) -> 2wm.has({}) -> falsewm.get(o3) -> {"a":"a"}TypeError: wm[Symbol.iterator] is not a function
代理(Proxy)
代理可以用来改变对象的行为。 它们允许我们定义 trap 。
var obj = function ProfanityGenerator() { return { words: "Horrible words" }}() var handler = function CensoringHandler() { return { get: function (target, key) { return target[key].replace("Horrible", "Nice"); }, } }() var proxy = new Proxy(obj, handler); console.log(proxy.words);
结果:
proxy.words -> Nice words
提供以下 trap :
var handler ={ get:..., set:..., has:..., deleteProperty:..., apply:..., construct:..., getOwnPropertyDescriptor:..., defineProperty:..., getPrototypeOf:..., setPrototypeOf:..., enumerate:..., ownKeys:..., preventExtensions:..., isExtensible:...}
Symbols 是一个新类型。 可用于创建匿名属性。
var typeSymbol = Symbol("type"); class Pet { constructor(type) { this[typeSymbol] = type; } getType() { return this[typeSymbol]; } } var a = new Pet("dog");console.log(a.getType());console.log(Object.getOwnPropertyNames(a)) console.log(Symbol("a") === Symbol("a"))
结果:
a.getType() -> dogObject.getOwnPropertyNames(a) -> []Symbol("a") === Symbol("a") -> false
可继承内置函数
我们现在可以继承原生类。
class CustomArray extends Array { } var a = new CustomArray(); a[0] = 2console.log(a[0])
结果:
a[0] -> 2
不能使用数组的代理(Proxy)来覆盖getter函数。
新类库
各种新的方法和常量
console.log(Number.EPSILON)console.log(Number.isInteger(Infinity))console.log(Number.isNaN("NaN")) console.log(Math.acosh(3))console.log(Math.hypot(3, 4))console.log(Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2)) console.log("abcde".includes("cd") )console.log("abc".repeat(3) ) console.log(Array.of(1, 2, 3) )console.log([0, 0, 0].fill(7, 1) )console.log([1, 2, 3].find(x => x == 3) )console.log([1, 2, 3].findIndex(x => x == 2)) console.log([1, 2, 3, 4, 5].copyWithin(3, 0)) console.log(["a", "b", "c"].entries() )console.log(["a", "b", "c"].keys() )console.log(["a", "b", "c"].values() ) console.log(Object.assign({}, { origin: new Point(0,0) }))
结果:
Number.EPSILON -> 2.220446049250313e-16Number.isInteger(Infinity) -> falseNumber.isNaN("NaN") -> falseMath.acosh(3) -> 1.7627471740390859Math.hypot(3, 4) -> 5Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) -> 2"abcde".includes("cd") -> true"abc".repeat(3) -> abcabcabcArray.of(1, 2, 3) -> [1,2,3][0, 0, 0].fill(7, 1) -> [0,7,7][1, 2, 3].find(x => x == 3) -> 3[1, 2, 3].findIndex(x => x == 2) -> 1[1, 2, 3, 4, 5].copyWithin(3, 0) -> [1,2,3,1,2]["a", "b", "c"].entries() -> {}["a", "b", "c"].keys() -> {}["a", "b", "c"].values() -> TypeError: ["a","b","c"].values is not a functionObject.assign({}, { origin: new Point(0,0) }) -> ReferenceError: Point is not defined文档: Number, Math, Array.from, Array.of, Array.prototype.copyWithin, Object.assign
二进制和八进制
二进制和八进制数字的字面量。
console.log(0b11111)console.log(0o2342) console.log(0xff); // also in es5
结果:
ES6 代码:0b11111 -> 310o2342 -> 12500xff -> 255
Promises
异步编程。
var p1 = new Promise((resolve, reject) => { setTimeout(() => resolve("1"), 101)})var p2 = new Promise((resolve, reject) => { setTimeout(() => resolve("2"), 100)}) Promise.race([p1, p2]).then((res) => { console.log(res)}) Promise.all([p1, p2]).then((res) => { console.log(res)})
结果:
res -> 2res -> ["1","2"]
快速的 Promise
var p1 = Promise.resolve("1")var p2 = Promise.reject("2") Promise.race([p1, p2]).then((res) => { console.log(res)})
结果:
res -> 1
快速失败
如果一个 promise 失败,all和race也将 reject(拒绝)。
var p1 = new Promise((resolve, reject) => { setTimeout(() => resolve("1"), 1001)})var p2 = new Promise((resolve, reject) => { setTimeout(() => reject("2"), 1)}) Promise.race([p1, p2]).then((res) => { console.log("success" + res)}, res => { console.log("error " + res)}) Promise.all([p1, p2]).then((res) => { console.log("success" + res)}, res => { console.log("error " + res)})
结果:
"error " + res -> error 2"error " + res -> error 2
反射(Reflect)
新类型的元编程与新的API现有的还有一些新的方法。
var z = {w: "Super Hello"}var y = {x: "hello", __proto__: z}; console.log(Reflect.getOwnPropertyDescriptor(y, "x"));console.log(Reflect.has(y, "w"));console.log(Reflect.ownKeys(y, "w")); console.log(Reflect.has(y, "x"));console.log(Reflect.deleteProperty(y,"x"))console.log(Reflect.has(y, "x"));
结果:
Reflect.getOwnPropertyDescriptor(y, "x") -> {"value":"hello","writable":true,"enumerable":true,"configurable":true}Reflect.has(y, "w") -> trueReflect.ownKeys(y, "w") -> ["x"]Reflect.has(y, "x") -> trueReflect.deleteProperty(y,"x") -> trueReflect.has(y, "x") -> false
尾调用(Tail Call)优化
尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。
ES6可以确保尾调用不会造成堆栈溢出。 (不是所有的实现工作)。
function factorial(n, acc = 1) { if (n <= 1) return acc; return factorial(n - 1, n * acc);}console.log(factorial(10))console.log(factorial(100))console.log(factorial(1000))console.log(factorial(10000))console.log(factorial(100000))console.log(factorial(1000000))
结果:
factorial(10) -> 3628800factorial(100) -> 9.332621544394418e+157factorial(1000) -> Infinityfactorial(10000) -> Infinityfactorial(100000) -> RangeError: Maximum call stack size exceededfactorial(1000000) -> RangeError: Maximum call stack size exceeded
- es6 新特性整理
- 【ES6】ES6的新特性
- es6-特性整理
- ES6特性整理
- ES6:JavaScript 新特性
- ES6新特性概览
- ES6新特性概览
- es6 新特性
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- ES6新特性概览
- es6新特性学习
- ES6新特性概览
- ES6新特性总结
- es6新特性概述
- ES6新特性
- ES6新特性概览
- 苹果Iphone/Ipad--L2TP虚拟教程
- nuts软件
- Eclipse使用maven搭建spring mvc的详细步骤
- Java设计模式之代理模式
- Azure上搭建AD RMS环境系列二 -- RMS群集安装及内网测试
- es6 新特性整理
- PAT (Advanced Level) Practise 1010. Radix (25)
- Android自定义View分享——打钩动画
- c和c++如何把一个整数转化为string
- Python数据分析模块 | pandas做数据分析(一):基本数据对象
- 自動加入import -- Android Studio ctrl shit o
- 安卓Android--PPTP教程
- 传值设置mybatis查询的 列名(字段名),以及如何查看mybatis中执行的SQL语句
- Linux进程状态