函数式编程
函数式编程JavaScript 语言从一诞生,就具有函数式编程的烙印。它将函数作为一种独立的数据类型,与其他数据类型处于完全平等的地位。在 JavaScript 语言中,你可以采用面向对象编程,也可以采用函数式编程。有人甚至说,JavaScript 是有史以来第一种被大规模采用的函数式编程语言。 ES6 的种种新增功能,使得函数式编程变得更方便、更强大。本章介绍 ES6 如何进行函数式编程。 柯里化柯里化(currying)指的是将一个多参数的函数拆分成一系列函数,每个拆分后的函数都只接受一个参数(unary)。 12345function add (a, b) { return a + b;}add(1, 1) // 2 上面代码中,函数add接受两个参数a和b。 柯里化就是将上面的函数拆分成两个函数,每个函数都只接受一个参数。 12345678910function add (a) { return function (b) { return a + b; }}// 或者采用箭头函数写法const a...
最新提案
最新提案本章介绍一些尚未进入标准、但很有希望的最新提案。 do 表达式本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。 1234{ let t = f(); t = t * t + 1;} 上面代码中,块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量。 现在有一个提案,使得块级作用域可以变为表达式,也就是说可以返回值,办法就是在块级作用域之前加上do,使它变为do表达式,然后就会返回内部最后执行的表达式的值。 1234let x = do { let t = f(); t * t + 1;}; 上面代码中,变量x会得到整个块级作用域的返回值(t * t + 1)。 do表达式的逻辑非常简单:封装的是什么,就会返回什么。 12345// 等同于 <表达式>do { <表达式>; }// 等同于 <语句>do { <语句> } do表达式的好处是可以封装多个语句...
SIMD
SIMD概述SIMD(发音/sim-dee/)是“Single Instruction/Multiple Data”的缩写,意为“单指令,多数据”。它是 JavaScript 操作 CPU 对应指令的接口,你可以看做这是一种不同的运算执行模式。与它相对的是 SISD(“Single Instruction/Single Data”),即“单指令,单数据”。 SIMD 的含义是使用一个指令,完成多个数据的运算;SISD 的含义是使用一个指令,完成单个数据的运算,这是 JavaScript 的默认运算模式。显而易见,SIMD 的执行效率要高于 SISD,所以被广泛用于 3D 图形运算、物理模拟等运算量超大的项目之中。 为了理解 SIMD,请看下面的例子。 123456789var a = [1, 2, 3, 4];var b = [5, 6, 7, 8];var c = [];c[0] = a[0] + b[0];c[1] = a[1] + b[1];c[2] = a[2] + b[2];c[3] = a[3] + b[3];c // Array[6, 8, 1...
参考链接
参考链接官方文件 ECMAScript® 2015 Language Specification: ECMAScript 2015 规格 ECMAScript® 2016 Language Specification: ECMAScript 2016 规格 ECMAScript® 2017 Language Specification:ECMAScript 2017 规格(草案) ECMAScript Current Proposals: ECMAScript 当前的所有提案 ECMAScript Active Proposals: 已经进入正式流程的提案 ECMAScript proposals:从阶段 0 到阶段 4 的所有提案列表 TC39 meeting agendas: TC39 委员会历年的会议记录 ECMAScript Daily: TC39 委员会的动态 The TC39 Process: 提案进入正式规格的流程 TC39: A Process Sketch, Stages 0 and 1: Stage 0 和 Stage 1 的含义 TC39 Process S...
Symbol
Symbol概述ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。 ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。 Symbol 值通过Symbol函数生成。这就是说,**对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。**凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。 1234let s = Symbol();typeof s// "symbol" 上面代码中,变量s就是一个独一无二的值。typeof运算符的结果...
正则的扩展
正则的扩展RegExp 构造函数在 ES5 中,RegExp构造函数的参数有两种情况。 第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag)。 123var regex = new RegExp('xyz', 'i');// 等价于var regex = /xyz/i; 第二种情况是,参数是一个正则表示式,这时会返回一个原有正则表达式的拷贝。 123var regex = new RegExp(/xyz/i);// 等价于var regex = /xyz/i; 但是,ES5 不允许此时使用第二个参数添加修饰符,否则会报错。 12var regex = new RegExp(/xyz/, 'i');// Uncaught TypeError: Cannot supply flags when constructing one RegExp from another ES6 改变了这种行为。如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且,返回的正则表达式...
async 函数
async 函数含义ES2017 标准引入了 async 函数,使得异步操作变得更加方便。 async 函数是什么?一句话,它就是 Generator 函数的语法糖。 前文有一个 Generator 函数,依次读取两个文件。 1234567891011121314151617const fs = require('fs');const readFile = function (fileName) { return new Promise(function (resolve, reject) { fs.readFile(fileName, function(error, data) { if (error) return reject(error); resolve(data); }); });};const gen = function* () { const f1 = yield readFile('/etc/fstab'); ...
Iterator 和 for-of 循环
Iterator 和 for…of 循环Iterator(遍历器)的概念JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象。这样就需要一种统一的接口机制,来处理所有不同的数据结构。 遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。 Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。 Iterator 的遍历过程是这样的。 (1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。 (2)第一次调用指针对象的next方法,可...
数值的扩展
数值的扩展二进制和八进制表示法ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。 120b111110111 === 503 // true0o767 === 503 // true 从 ES5 开始,在严格模式之中,八进制就不再允许使用前缀0表示,ES6 进一步明确,要使用前缀0o表示。 12345678910// 非严格模式(function(){ console.log(0o11 === 011);})() // true// 严格模式(function(){ 'use strict'; console.log(0o11 === 011);})() // Uncaught SyntaxError: Octal literals are not allowed in strict mode. 如果要将0b和0o前缀的字符串数值转为十进制,要使用Number方法。 12Number('0b111') // 7Number('0o10...
Generator 函数的语法
Generator 函数的语法简介基本概念Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。本章详细介绍 Generator 函数的语法和 API,它的异步编程应用请看《Generator 函数的异步应用》一章。 Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。 执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。 形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。 1234567function* helloWorldGenerator() { yield 'hello'; yield 'world'...








