浅尝ECMAScript6

简介

ECMAScript6 是最新的ECMAScript标准,于2015年6月正式推出(所以也称为ECMAScript 2015),相比于2009年推出的es5, es6定义了更加丰富的语言特性,基于该标准的Javascript语言也迎来了语法上的重大变革。本文列举了部分es6新特性,希望之前没接触es6的小伙伴读完本文能对下一代js编程有一个初步的认识。

箭头函数

箭头函数用 "=>"简化函数定义,类似于C#, Java8中的Lambda表达式,支持语句块和表达式函数体,和普通函数的唯一区别在于函数体引用的 this 和包裹代码的this一致。

// 表达式
var odds = evens.map(v => v + 1);
var nums = evens.map((v, i) => v + i);
var pairs = evens.map(v => ({even: v, odd: v + 1})); // 代码块
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
}); // this , 这里 this引用 leon
var bob = {
_name: "leon",
_friends: [],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f));
}
}

ES6的类简单而言只是基于原型继承的语法糖, 使用方便的声明式定义,使得类型定义和其他面向对象语言一致。类支持原型继承,父类调用,实体和静态方法以及构造函数。

'use strict'

class Animal {
constructor(name) {
this.name = name;
} speak(msg) {
console.log(`${this.name} says ${msg}`);
} static fight(a, b) {
console.log(`${a.name} and ${b.name} are fighting!`);
} } class Dog extends Animal {
constructor(name) {
super('DOG' + name);
}
} let dogA = new Dog('foo');
let dogB = new Dog('bar'); dogA.speak('hi');
dogB.speak(`what's up`)
Animal.fight(dogA, dogB); /**
*DOGfoo says hi
*DOGbar says what's up
*DOGfoo and DOGbar are fighting!
*/

增强的对象字面量

对象字面量现在支持在对象构建时设置原型对象,定义方法,调用父类构造函数,以及用表达式计算属性. 这些特性使得对象字面量定义和类型定义十分相似, 给基于对象的设计带来了便利。

var obj = {
// 原型对象
__proto__: theProtoObj,
// 简化定义成员, ‘handler: handler’
handler,
// 方法
toString() {
// 父类调用
return "d " + super.toString();
},
// 动态属性名
[ 'prop_' + (() => 42)() ]: 42
};

模板字符串

模板字符串提供了一种构建字符串的语法糖,类似于Perl, Python和其他语言中的字符串插值特性.

// 多行字符串
`In JavaScript this is
not legal.` // 字符串插值
var name = "Leon", time = "today";
`Hello ${name}, how are you ${time}?`

解构赋值

解构赋值允许你使用类似数组或对象字面量的语法将数组和对象的属性赋给各种变量。这种赋值语法极度简洁,同时还比传统的属性访问方法更为清晰。

// 数组  a=1,b=2,c=3
var [a, b, c] = [1,2,3]; // 数组,没有匹配的返回undefined , a=1,b=2,c=undefined
var [a, b, c] = [1,2]; // 对象, m='leon', n=18
var {name:m,age:n}={name:'leon',age:18} // 对象属性名与变量名一致时,可以简写为
var {foo,bar}={foo:'1',bar:2} // 嵌套 name='leon'
var {x:{y:{z:name}}}={x:{y:{z:'leon'}}}

默认参数和不定参数

函数调用者不需要传递所有可能存在的参数,没有被传递的参数由默认参数进行填充。 在所有函数参数中,只有最后一个才可以被标记为不定参数。函数被调用时,不定参数前的所有参数都正常填充,任何“额外的”参数都被放进一个数组中并赋值给不定参数。如果没有额外的参数,不定参数就是一个空数组,它永远不会是undefined。

// 默认参数
function f(x, y=12) {
// 如果没有传入y 或传入的值为undefined ,则y=12
return x + y;
}
f(3) == 15
// 不定参数
function f(x, ...y) {
// y 是一个数组
return x * y.length;
}
f(3, "hello", true) == 6
function f(x, y, z) {
return x + y + z;
}
// 数组中的每个元素作为参数传入
f(...[1,2,3]) == 6

let + const 块级作用域变量

let 和 const 声明的变量具有块级作用域, 传统使用var申明的变量在整个函数内都可访问。const声明的变量只可以在声明时赋值,不可随意修改,否则会导致SyntaxError(语法错误)。

function f() {
{
let x;
{
const x = "me";
// 因为是const, 所以不可修改,报错
x = "foo";
}
// 报错, 用let重定义变量会抛出一个语法错误
let x = "inner";
}
}

迭代器 和 for..of

迭代器类似于 .NET CLR 的 IEnumerable 或 Java 的 Iterable, 所有拥有[Symbol.iterator]的对象被称为可迭代的, 而 for ..of 用于遍历实现了迭代器方法的对象,比如Array, Map, Set, Array-like Object

for (var value of [1,2,3]) {
// 依次打印 1,2,3
console.log(value);
}

生成器

生成器对象由生成器函数(function* 定义的函数)返回,它同时准守iterator 和 Iterable 协议。著名的koa nodejs框架就是基于此特性构建。

'use strict'

function* gen(i){
yield i+1;
yield i+2;
} function* gen1(i){
yield i;
yield* gen(i); // delegate to gen, after gen finished , delegate back and continue
yield i+3; return 'finished';
} let g=gen1(10); // g is a generator object
console.log(g.next().value); //
console.log(g.next().value); //
console.log(g.next().value); //
console.log(g.next().value); //
console.log(g.next().value); // finished
console.log(g.next().value); // undefined
 

模块

模块已经得到语言级别的支持,ES6的模块设计参照了AMD CommonJS 规范。

// lib/math.js
// export 定义要导出的对象
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593; // 没加export, 所以foo不被导出
function foo(){}
// app.js
// 导入全部在lib/math.js中标记为导出的对象
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
// 显示标记需要导入的成员
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));
// lib/mathplusplus.js
// 导入lib/math中的全部对象并重新导出
export * from "lib/math";
export var e = 2.71828182846;
// 默认导出对象
export default function(x) {
return Math.log(x);
}
// app.js
// ln为上面的默认导出对象, pi来自于lib/math,e来自于mathplusplus
import ln, {pi, e} from "lib/mathplusplus";
alert("2π = " + ln(e)*pi*2);

Map + Set + WeakMap + WeakSet

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true; // Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34; // Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined // Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });

Symbol

Symbol是es6新添加的一个基元数据类型, 其他的基元类型有string,number,boolean,null,undefined. Symbol是唯一的,一般用作对象的key以存取相关状态信息。

'use strict'

//A symbol is a unique and immutable data type and may be used as an identifier for object properties.
//Symbol([description])
let s1 = Symbol();
let s2 = Symbol('hi');
let s3 = Symbol('how are you'); let obj = {[s1]: 18}; // need [] to wrap
obj[s2] = "hello";
console.log(obj[s1]); //
console.log(obj[s2]); //hello obj[s3] = `I'm fine,thank you`; for (let s of Object.getOwnPropertySymbols(obj)) {
/**
Symbol()
Symbol(hi)
Symbol(how are you)
* */
console.log(s);
} var ar = Object.getOwnPropertySymbols(obj);
console.log(ar.length); // 3

子类化内置对象

ES6中的内置对象,比如 Array, Date 等可以被子类继承

// 这里定义一个Array的子类MyArray
class MyArray extends Array {
constructor(...args) { super(...args); }
}

Math + Number + String + Array + Object 新增的方法和属性

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) //
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // "abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc" Array.from(document.querySelectorAll('*')) // 返回一个真实的数组
[1, 2, 3].find(x => x == 3) //
[1, 2, 3].findIndex(x => x == 2) //
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c" Object.assign(Point, { origin: new Point(0,0) })

二进制和八进制字面量

// 二进制
0b111110111 === 503 // true // 八进制
0o767 === 503 // true

Promises

Promise 是异步编程的一种规范,解决了js异步编程中callback hell问题, 在es6中原生支持.

'use strict'

let p=new Promise(function(resolve,reject){
setTimeout(function(){
resolve(1);
},100);
}); p.then(function(v){
console.log(`the previous function returned ${v}`);
}); Promise.resolve(1).then(function(v){
console.log(v); //
}).catch(function(r){
console.log(r);
}); Promise.reject('failed-leon').then(function(v){
console.log(v);
}).catch(function(r){
console.log(r); // failed-leon
}); Promise.reject('failed').then(function(v){
console.log(v);
},function(r){
console.log(r+'0'); // failed0
}).catch(function(r){
console.log(r+'1'); // not executed
}); //Returns a promise that either resolves when all of the promises in the iterable argument have resolved or rejects as soon as one of the promises in the iterable argument rejects. If the returned promise resolves, it is resolved with an array of the values from the resolved promises in the iterable. If the returned promise rejects, it is rejected with the reason from the promise in the iterable that rejected. This method can be useful for aggregating results of multiple promises together.
Promise.all([Promise.resolve(1),Promise.resolve(2),Promise.resolve(3)]).then(function(vs){
for(let v of vs){
console.log(v); // 1 2 3
}
}); //Returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
Promise.race([Promise.resolve('a'),Promise.resolve('b'),Promise.resolve('c')]).then(function(v){
console.log(v); // a
});
 

结语

除了以上特性,es6还增强了对unicode编码的支持,以便更好的支持应用国际化, 还有代理等等特性,这里就不一一列举了,目前javascript开发范围越来广泛,web, 移动应用,智能家居...2015年中旬es6规范正式推出,尽管当前各厂商浏览器js引擎对es6还没有完全支持,但是新版的nodejs已经默认支持了大部分es6特性,而且我们还可以利用babel将es6编译成es5供浏览器端使用。另外对于.net/java程序员而言,新增的es6特性无需费多大力气就可以熟悉,所以还没有开始接触es6的小伙伴现在可以投入es6的怀抱,用js去改变世界了!

浅尝ECMAScript6的更多相关文章

  1. 浅尝key-value数据库(二)——MongoDB的优与劣

    浅尝key-value数据库(二)——MongoDB的优与劣 MongoDB的名字取自英文单词"humongous"的中间五个字母,是一个C++开发的基于分布式文件存储的数据库开源 ...

  2. 浅尝key-value数据库(三)——MongoDB的分布式

    浅尝key-value数据库(三)——MongoDB的分布式 测试了单机MongoDB的随机读和写入性能,这一节来讲一讲MongoDB的分布式. MongoDB的分布式分成两种,一种是Replicat ...

  3. 浅尝key-value数据库(一)——一览NoSQL

    浅尝key-value数据库(一)——一览NoSQL 最近由于一个项目的关系,研究了一下key-value数据库这个最近很火的概念.本系列从项目需求的角度分析并测试了几个key-value数据库的性能 ...

  4. Python图形界面开发编程:wxPython(浅尝篇)

    Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 ...

  5. 浅尝Go语言GC

    大家好,我是小栈君,因为个人和工作的缘故,所以拖更了一点时间,但是关于拖更的内容小栈君会在后续的时间中补回来,还希望大家继续支持和关注小栈君.当然,在国内疫情稍微减缓的情况下,小栈君在这里也多说两句, ...

  6. 浅尝装饰器和AOP

    [写在前面] 参考文章:https://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html[从简单的例子入手进行讲解,由浅入深,很到位] 装饰器部 ...

  7. 浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含自定义扫描组件.自定义导入组件.手动注册组件.自动注入方法和参数.使用Spring容器底层组件等 配置 @Confi ...

  8. 浅尝Spring注解开发_Bean生命周期及执行过程

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期.自定义初始化方法.Debug BeanPostProcessor执行过程及在Spring底层中的应 ...

  9. 浅尝Spring注解开发_AOP原理及完整过程分析(源码)

    浅尝Spring注解开发_AOP原理及完整过程分析(源码) 浅尝Spring注解开发,基于Spring 4.3.12 分析AOP执行过程及源码,包含AOP注解使用.AOP原理.分析Annotation ...

随机推荐

  1. 浅谈PHP7新特性

    1. 运算符(NULL 合并运算符) 把这个放在第一个说是因为我觉得它很有用.用法: $a = $_GET['a'] ?? 1; 它相当于: $a = isset($_GET['a']) ? $_GE ...

  2. 用微信小程序开发的Canvas绘制可配置的转盘抽奖

    使用https://github.com/givebest/GB-canvas-turntable代码移植过而来. 其它 微信小程序感觉是个半成品,代码移植过程比较繁琐麻烦.canvas API 部分 ...

  3. 拒绝了对对象 'base_config' (数据库 '****',架构 'dbo')的 SELECT 权限

    在网上看了很多资料都是空说一谈,都只是说很简单,然后没有说遇到这样的情况具体该怎么做,看到这里都知道是权限问题,其实我们每一个人都知道,又是我觉得我还是要给以后遇到的朋友个解决方法:  这里用到的数据 ...

  4. 注册GitHub和源程序版本管理软件和项目管理软件的优缺点

    目前市面上主要源程序管理软件主要有:Microsoft TFS(Team Foundation Server).GitHub.Trac.BUGZILLA.Apple XCode.SVN Microso ...

  5. 一劳永逸:域名支持通配符,ASP.NET Core中配置CORS更轻松

    ASP.NET Core 内置了对 CORS 的支持,使用很简单,只需先在 Startup 的 ConfigureServices() 中添加 CORS 策略: public void Configu ...

  6. ABP理论学习之审计日志

    返回总目录 本篇目录 介绍 配置 通过特性开启/关闭 注意 我项目中的例子 介绍 维基百科说: "审计跟踪(也叫审计日志)是与安全相关的按照时间顺序的记录,记录集或者记录源,它们提供了活动序 ...

  7. 基础知识漫谈(2):从设计UI框架开始

    说UI能延展出一丢丢的东西来,光java就有swing,swt/jface乃至javafx等等UI toolkit,在桌面上它们甚至都不是主流,在web端又有canvas.svg等等. 基于这些UI工 ...

  8. ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程

    好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: --> 开篇:上一篇 ...

  9. Redis系列(三)-Redis发布订阅及客户端编程

    阅读目录 发布订阅模型 Redis中的发布订阅 客户端编程示例 0.3版本Hredis 发布订阅模型 在应用级其作用是为了减少依赖关系,通常也叫观察者模式.主要是把耦合点单独抽离出来作为第三方,隔离易 ...

  10. 表格搞定 Asp.net Web 状态管理

    最近在网上搜罗了 ASP.NET WEB 状态管理方面的一些内容,终于把这些内容整合总结了一下. 1. 希望自己通过整理,能够掌握一些,为自己投资. 2. 以便自己忘记,又要浪费时间搜罗. 3. 希望 ...