diff --git a/docs/class.md b/docs/class.md index 5d539d0..2e268bb 100644 --- a/docs/class.md +++ b/docs/class.md @@ -1,4 +1,6 @@ -# class +# Class和Module + +## Class ES6引入了Class(类)这个概念,可以定义class,作为对象的模板。 @@ -41,3 +43,89 @@ class ColorPoint extends Point { ``` 上面代码定义了一个ColorPoint类,该类通过extends关键字,继承了Point类的所有属性和方法。在constructor方法内,super就指代父类Point。 + +## Module的基本用法 + +ES6允许将独立的js文件作为模块,也就是说,允许一个JavaScript脚本文件调用另一个脚本文件,从而使得模块化编程成为可能。 + +假设有一个circle.js,它是一个单独模块。 + +```javascript + +// circle.js + +export function area(radius) { + return Math.PI * radius * radius; +} + +export function circumference(radius) { + return 2 * Math.PI * radius; +} + +``` + +上面代码中的export关键字,表示这个方法是对外开放的接口。 + +然后,main.js引用这个模块。 + +```javascript + +// main.js + +import { area, circumference } from 'circle'; + +console.log("圆面积:" + area(4)); +console.log("圆周长:" + circumference(14)); + +``` + +import语句用来导入模块,它接受一个对象,里面指定所要导入的方法,后面的from指定模块名。 + +另一种写法是使用module命令,整体加载circle.js。 + +```javascript + +// main.js + +module circle from 'circle'; + +console.log("圆面积:" + circle.area(4)); +console.log("圆周长:" + circle.circumference(14)); + +``` + +module命令跟一个变量,表示加载的模块定义在该变量上。 + +## 模块的继承 + +模块之间也可以继承。 + +假设有一个circleplus模块,继承了circle模块。 + +```javascript + +// circleplus.js + +export * from 'circle'; +export var e = 2.71828182846; +export default function(x) { + return Math.exp(x); +} + +``` + +上面代码中的“export *”,表示导入circle模块的所有属性和方法。export default命令表示,定义模块的默认方法。 + +加载上面模块的写法如下。 + +```javascript + +// main.js + +module math from "circleplus"; +import exp from "circleplus"; +console.log(exp(math.pi)); + +``` + +上面代码中的"import exp"表示,将circleplus模块的默认方法加载为exp方法。 diff --git a/docs/destructuring.md b/docs/destructuring.md new file mode 100644 index 0000000..8bb52fa --- /dev/null +++ b/docs/destructuring.md @@ -0,0 +1,121 @@ +# 多变量的模式赋值 + +ES6允许按照一定模式,一次性对多个变量进行赋值,这又称为解构(Destructuring)。 + +正常情况下,将数组元素赋值给多个变量,只能一次次分开赋值。 + +```javascript + +var a = 1; +var b = 2; +var c = 3; + +``` + +ES6允许写成下面这样。 + +```javascript + +var [a, b, c] = [1, 2, 3]; + +``` + +本质上,这种写法属于模式匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些嵌套数组进行模式赋值的例子。 + +```javascript + +var [foo, [[bar], baz]] = [1, [[2], 3]] + +var [,,third] = ["foo", "bar", "baz"] + +var [head, ...tail] = [1, 2, 3, 4] + +``` + +模式赋值还允许指定默认值。 + +```javascript + +var [missing = true] = []; + +console.log(missing) +// true + +var { x = 3 } = {}; +console.log(x) +// 3 + +``` + +模式赋值不仅可以用于数组,还可以用于对象。 + +```javascript + +var { foo, bar } = { foo: "lorem", bar: "ipsum" }; + +foo // "lorem" +bar // "ipsum" + +var o = { + p1: [ + "Hello", + { p2: "World" } + ] +}; + +var { a: [x, { y }] } = o; + +x // "Hello" +y // "World" + +``` + +这种写法的用途很多。 + +(1)交换变量的值 + +```javascript + +[x, y] = [y, x]; + +``` + +(2)从函数返回多个值 + +```javascript + +function example() { + return [1, 2, 3]; +} + +var [a, b, c] = example(); + +``` + +(3)函数参数的定义 + +```javascript + +function f({p1, p2, p3}) { + // ... +} + +``` + +(4)函数参数的默认值 + +```javascript + +jQuery.ajax = function (url, { + async = true, + beforeSend = function () {}, + cache = true, + complete = function () {}, + crossDomain = false, + global = true, + // ... more config +}) { + // ... do stuff +}; + +``` diff --git a/docs/let.md b/docs/let.md index ced3228..0d83695 100644 --- a/docs/let.md +++ b/docs/let.md @@ -1,6 +1,6 @@ # let和const命令 -## let命令概述 +## let命令 ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。 diff --git a/docs/object.md b/docs/object.md index 4a8691f..dd5ce9a 100644 --- a/docs/object.md +++ b/docs/object.md @@ -160,3 +160,43 @@ let obj = { obj[specialMethod](123); ``` + +## Proxy + +所谓Proxy,可以理解成在目标对象之前,架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,可以被过滤和改写。 + +ES6原生提供Proxy构造函数,用来生成proxy实例对象。 + +```javascript + +var proxy = new Proxy({}, { + get: function(target, property) { + return 35; + } +}); + +proxy.time // 35 +proxy.name // 35 +proxy.title // 35 + +``` + +上面代码就是Proxy构造函数使用实例,它接受两个参数,第一个所要代理的目标对象(上例是一个空对象),第二个是拦截函数,它有一个get方法,用来拦截对目标对象的访问请求。get方法的两个参数分别是目标对象和所要访问的属性。可以看到,由于拦截函数总是返回35,所以访问任何属性都得到35。 + +下面是另一个拦截函数的例子。 + +```javascript + +var proxy = new Proxy(target, { + get: function(target, property) { + if (property in target) { + return target[property]; + } else { + throw new ReferenceError("Property \"" + property + "\" does not exist."); + } + } +}); + +``` + +上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回undefined。 diff --git a/docs/set-map.md b/docs/set-map.md index 03ca161..3c4a5f3 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -241,7 +241,7 @@ map.forEach(function(value, key, map) { 上面代码中,forEach方法的回调函数的this,就指向reporter。 -## WeakMap结构 +## WeakMap WeakMap结构与Map结构基本类似,唯一的区别是它只接受对象作为键名(null除外),不接受原始类型的值作为键名。 diff --git a/docs/string.md b/docs/string.md index 4f99549..b65eed2 100644 --- a/docs/string.md +++ b/docs/string.md @@ -221,3 +221,29 @@ var r = /hello\d/y; r.sticky // true ``` + +## 模板字符串 + +模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。 + +```javascript + +// 普通字符串 +`In JavaScript '\n' is a line-feed.` + +// 多行字符串 +`In JavaScript this is + not legal.` + +// 字符串中嵌入变量 +var name = "Bob", time = "today"; +`Hello ${name}, how are you ${time}?` + +var x = 1; +var y = 2; +console.log(`${ x } + ${ y } = ${ x + y}`) +// "1 + 2 = 3" + +``` + +上面代码表示,在模板字符串中嵌入变量,需要将变量名写在${}之中。 diff --git a/sidebar.md b/sidebar.md index 82a40cc..93c6472 100644 --- a/sidebar.md +++ b/sidebar.md @@ -8,6 +8,7 @@ - [前言](#README) - [ECMAScript 6简介](#docs/intro) - [let和const命令](#docs/let) +- [多变量的模式赋值](#docs/destructuring) - [字符串的扩展](#docs/string) - [数值的扩展](#docs/number) - [对象的扩展](#docs/object) @@ -16,7 +17,7 @@ - [Iterator和for...of循环](#docs/iterator) - [Generator函数](#docs/generator) - [Promise对象](#docs/promise) -- [Class](#docs/class) +- [Class和Module](#docs/class) - [参考链接](#docs/reference) ## 其他