ECMAScript6(ECMAScript 2015 ,ES5,ES2016)技术已经在前端圈子很流行了,他给前端开发人员带来了很多惊喜,提供的语法糖使复杂的操作变得简单。
本文没有详细描述这些新特性,因为网上都已经有很多相关的介绍了。主要针对ES6 新特性收集了相关范例代码,他可以让你快速了解这个新的javascript规范。
箭头函数
function()
函数的简写表示法,但它不绑定 this
。
v + 1); // no parentes and no brackets var nums = evens.map((v,i) => v + i); var pairs = evens.map(v => ({even: v,odd: v + 1}));// Statement bodies
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});
this
是如何工作的?
this.name,regularGetName: function() { return this.name },arrowGetThis: () => this,regularGetThis: function() { return this } }console.log(this.name)
console.log(object.arrowGetName());
console.log(object.arrowGetThis());
console.log(this)
console.log(object.regularGetName());
console.log(object.regularGetThis());
结果:
object.arrowGetName() -> object.arrowGetThis() -> [object Window] this -> [object Window] object.regularGetName() -> Name object.regularGetThis() -> {"name":"Name"}
Classes(类)
我们知道“真正”语言中的类(Classes)。在 ES6 中类(Classes)其实是原型继承的语法糖。
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();
}
}
增强的对象字面量
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};
console.log(obj.handler)
console.log(obj.handler())
console.log(obj.toString())
console.log(obj.prop_42)
结果:
() => "handler" obj.handler() -> handler obj.toString() -> d The ProtoOBject To string obj.prop_42 -> 42
字符串插值
字符串插值的好语法
字符串插值
var multiLine = `ThisLine
Spans Multiple
Lines`
console.log(
Hello ${name},how are you ${time}?
)
console.log(multiLine)
结果:
Hello Bob,how are you today? multiLine -> This Line Spans Multiple Lines
解构 Destructuring
愚人码头注:列表匹配
结果:
1 b -> 3对象也能很好的解构
{ 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 b -> b c -> c使用速记表示法。
{ return {lhs: "a",op: "b",rhs: "c"}}// binds
op
,lhs
andrhs
in scope
var {op,lhs,rhs} = nodes()console.log(op)
console.log(lhs)
console.log(rhs)结果:
b lhs -> a rhs -> c可在参数位置使用
function m({name}) {
return name
}console.log(g({name: 5}))
console.log(m({name: 5}))结果:
5 m({name: 5}) -> 5故障弱化解构
结果:
undefined b -> 1 c -> []参数默认值(Default)
console.log(f(3))
console.log(f(3,2))结果:
15 f(3,2) -> 5扩展(Spread)
在函数中:
结果:
6在数组中:
console.log(lyrics)结果:
["head","shoulders","knees","toes"]扩展 + 对象字面量
我们可以使用这个创造很酷的对象。
// Spread properties
let n = { x,...z };
console.log(n); // { x: 1,b: 4 }
console.log(obj)可惜的是它还不支持:
npm install --save-dev babel-plugin-transform-object-rest-spread
Rest
我们可以使用 rest 操作符来允许无限参数。
console.log(demo(1,3,4,5,6))结果:
{"part1":1,"part2":[2,6]}Let
let
是新的var
。 因为它有块级作用域。{
let globalLet = "from demo2";
}console.log(globalVar)
console.log(globalLet)结果:
from demo1 globalLet -> ReferenceError: globalLet is not defined但是,它不会向
window
分配任何内容:console.log(window.me);
console.log(window.i);结果:
undefined window.i -> able不能使用
let
重新声明一个变量:结果:
SyntaxError: Identifier 'me' has already been declared结果:
barConst
const
是只读变量。结果:
应该注意,const 对象仍然可以被改变的。
结果:
{"a":"b"}For..of
迭代器的新类型,可以替代
for..in
。 它返回的是值而不是keys
。console.log(list)for (let i in list) {
console.log(i);
}结果:
[4,6] i -> 0 i -> 1 i -> 2console.log(list)for (let i of list) {
console.log(i);
}结果:
[4,6] i -> 4 i -> 5 i -> 6迭代器(Iterators)
迭代器是一个比数组更动态的类型。
console.log("start");for (var n of infinite) {
// truncate the sequence at 1000
if (n > 10)
break;
console.log(n);
}结果:
start n -> 1 n -> 2 n -> 3 n -> 4 n -> 5 n -> 6 n -> 7 n -> 8 n -> 9 n -> 10使用Typescript,我们可以看到它接口的样子:
生成器(Generators)
生成器创建迭代器,并且比迭代器更具动态性。他们不必以相同的方式跟踪状态 并不支持
done
的概念。console.log("start")
for (var n of infinity) {
// truncate the sequence at 1000
if (n > 10)
break;
console.log(n);
}结果:
start n -> 1 n -> 2 n -> 3 n -> 4 n -> 5 n -> 6 n -> 7 n -> 8 n -> 9 n -> 10使用Typescript 再次显示接口:
function* Iterators and generator
一个产量的例子*
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);结果:
10 gen.next().value -> 11 gen.next().value -> 12 gen.next().value -> 13 gen.next().value -> 20Unicode
ES6 为Unicode 提供了更好的支持。
console.log(regex.unicode)
console.log("\uD842\uDFD7")
console.log("\uD842\uDFD7".codePointAt())结果:
true "" -> "".codePointAt() -> 134103模块和模块加载器
原生支持模块。
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,nameN } from …;
export { import1 as name1,import2 as name2,nameN } from …;Set
Set 为数学对应,其中所有项目都是唯一的。对于知道sql的人来说,这相当于
distinct
。for(var item of set) {
console.log(item)
}结果:
2 set.has("Tomato") -> true item -> Potato item -> TomatoWeakSet
WeakSet对象允许您在集合中存储弱持有的对象。没有引用的对象将被垃圾回收。
for(let item of set) {
console.log(item)
}结果:
undefined set.has({a:"Tomato"}) -> false set.has(item) -> true TypeError: set[Symbol.iterator] is not a functionMap
Map 也称为词典。
console.log(map.get("Potato"))for(let item of map) {
console.log(item)
}for(let item in map) {
console.log(item)
}结果:
12 item -> ["Potato",12] item -> ["Tomato",34]可以使用除字符串之外的其他类型。
console.log(map.get(key))
console.log(map.get({a: "a"}))结果:
12 map.get({a: "a"}) -> undefinedWeakMap
使用键的对象,并且只保留对键的弱引用。
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)
}结果:
2 wm.has({}) -> false wm.get(o3) -> {"a":"a"} TypeError: wm[Symbol.iterator] is not a function代理(Proxy)
代理可以用来改变对象的行为。 它们允许我们定义 trap 。
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);
结果:
Nice words提供以下 trap :
Symbols
Symbols 是一个新类型。 可用于创建匿名属性。
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"))
结果:
dog Object.getOwnPropertyNames(a) -> [] Symbol("a") === Symbol("a") -> false可继承内置函数
我们现在可以继承原生类。
}var a = new CustomArray();
a[0] = 2
console.log(a[0])结果:
2不能使用数组的代理(Proxy)来覆盖getter函数。
新类库
各种新的方法和常量。
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,3) )
console.log([0,0].fill(7,1) )
console.log([1,3].find(x => x == 3) )
console.log([1,3].findIndex(x => x == 2))
console.log([1,5].copyWithin(3,0))
console.log(["a","b","c"].entries() )
console.log(["a","c"].keys() )
console.log(["a","c"].values() )console.log(Object.assign({},{ origin: new Point(0,0) }))
结果:
2.220446049250313e-16 Number.isInteger(Infinity) -> false Number.isNaN("NaN") -> false Math.acosh(3) -> 1.7627471740390859 Math.hypot(3,4) -> 5 Math.imul(Math.pow(2,32) - 2) -> 2 "abcde".includes("cd") -> true "abc".repeat(3) -> abcabcabc Array.of(1,3) -> [1,3] [0,1) -> [0,7,7] [1,3].find(x => x == 3) -> 3 [1,3].findIndex(x => x == 2) -> 1 [1,0) -> [1,1,2] ["a","c"].entries() -> {} ["a","c"].keys() -> {} ["a","c"].values() -> TypeError: ["a","c"].values is not a function Object.assign({},0) }) -> ReferenceError: Point is not defined文档: Number,Math,Array.from,Array.of,Array.prototype.copyWithin,Object.assign
二进制和八进制
二进制和八进制数字的字面量。
console.log(0xff); // also in es5结果:
31 0o2342 -> 1250 0xff -> 255Promises
异步编程。
{ 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)
})结果:
2 res -> ["1","2"]快速的 Promise
Promise.race([p1,p2]).then((res) => {
console.log(res)
})结果:
1快速失败
如果一个 promise 失败,
all
和race
也将 reject(拒绝)。{ setTimeout(() => reject("2"),1) })Promise.race([p1,p2]).then((res) => {
console.log("success" + res)
},res => {
console.log("error " + res)
})Promise.all([p1,res => {
console.log("error " + res)
})结果:
error 2 "error " + res -> error 2反射(Reflect)
新类型的元编程与新的API现有的还有一些新的方法。
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"));结果:
{"value":"hello","writable":true,"enumerable":true,"configurable":true} Reflect.has(y,"w") -> true Reflect.ownKeys(y,"w") -> ["x"] Reflect.has(y,"x") -> true Reflect.deleteProperty(y,"x") -> true Reflect.has(y,"x") -> false尾调用(Tail Call)优化
尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。
ES6可以确保尾调用不会造成堆栈溢出。 (不是所有的实现工作)。
结果:
3628800 factorial(100) -> 9.332621544394418e+157 factorial(1000) -> Infinity factorial(10000) -> Infinity factorial(100000) -> RangeError: Maximum call stack size exceeded factorial(1000000) -> RangeError: Maximum call stack size exceeded原文:ES6 Features
原文链接:https://www.f2er.com/js/40459.html