From 8b9202cd6c73ac9b35714e16d9184ccd902e6f3d Mon Sep 17 00:00:00 2001 From: ruanyf Date: Thu, 21 Jul 2016 21:41:19 +0800 Subject: [PATCH] docs(symbol): add an example of Singleton --- docs/intro.md | 8 +++---- docs/reference.md | 1 + docs/symbol.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/docs/intro.md b/docs/intro.md index 2ae49ac..5ad689a 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -1,10 +1,10 @@ # ECMAScript 6简介 -ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 +ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 -标准的制定者有计划,以后每年发布一次标准,使用年份作为标准的版本。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。 +标准的制定者有计划,以后每年发布一次标准,使用年份作为版本。因为ES6的第一个版本是在2015年发布的,所以又称ECMAScript 2015(简称ES2015)。 -2016年6月,发布了小幅修订的《ECMAScript 2016 标准》(简称 ES2016)。由于变动非常小(只新增了数组实例的`includes`方法和指数运算符),因此 ES2016 与 ES2015 基本上是同一个标准,都被看作是 ES6。根据计划,2017年6月将发布 ES2017 标准。 +2016年6月,小幅修订的《ECMAScript 2016 标准》(简称 ES2016)如期发布。由于变动非常小(只新增了数组实例的`includes`方法和指数运算符),因此 ES2016 与 ES2015 基本上是同一个标准,都被看作是 ES6。根据计划,2017年6月将发布 ES2017。 ## ECMAScript和JavaScript的关系 @@ -14,7 +14,7 @@ ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经 该标准从一开始就是针对JavaScript语言制定的,但是之所以不叫JavaScript,有两个原因。一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。 -因此,ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。在日常场合,这两个词是可以互换的。 +因此,ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。日常场合,这两个词是可以互换的。 ## ECMAScript的历史 diff --git a/docs/reference.md b/docs/reference.md index 167229f..e25947a 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -108,6 +108,7 @@ - Jason Orendorff, [ES6 In Depth: Symbols](https://hacks.mozilla.org/2015/06/es6-in-depth-symbols/) - Keith Cirkel, [Metaprogramming in ES6: Symbols and why they're awesome](http://blog.keithcirkel.co.uk/metaprogramming-in-es6-symbols/): Symbol的深入介绍 - Axel Rauschmayer, [Customizing ES6 via well-known symbols](http://www.2ality.com/2015/09/well-known-symbols-es6.html) +- Derick Bailey, [Creating A True Singleton In Node.js, With ES6 Symbols](https://derickbailey.com/2016/03/09/creating-a-true-singleton-in-node-js-with-es6-symbols/) ## 二进制数组 diff --git a/docs/symbol.md b/docs/symbol.md index 63e79ad..789c76b 100644 --- a/docs/symbol.md +++ b/docs/symbol.md @@ -377,6 +377,64 @@ iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo') 上面代码中,iframe窗口生成的Symbol值,可以在主页面得到。 +## 实例:模块的 Singleton 模式 + +Singleton模式指的是调用一个类,任何时候返回的都是同一个实例。 + +对于 Node 来说,模块文件可以看成是一个类。怎么保证每次执行这个模块文件,返回的都是同一个实例呢? + +很容易想到,可以把实例放到顶层对象`global`。 + +```javascript +// mod.js +function A() { + this.foo = 'hello'; +} + +if (!global._foo) { + global._foo = new A(); +} + +module.exports = global._foo; +``` + +然后,加载上面的`mod.js`。 + +```javascript +var a = require('./mod.js'); +console.log(a.foo); +``` + +上面代码中,变量`a`任何时候加载的都是`A`的同一个实例。 + +但是,这里有一个问题,全局变量`global._foo`是可写的,任何文件都可以修改。 + +```javascript +var a = require('./mod.js'); +global._foo = 123; +``` + +上面的代码,会使得别的脚本加载`mod.js`都失真。 + +为了防止这种情况出现,我们就可以使用Symbol。 + +```javascript +// mod.js +const FOO_KEY = Symbol.for('foo'); + +function A() { + this.foo = 'hello'; +} + +if (!global[FOO_KEY]) { + global[FOO_KEY] = new A(); +} + +module.exports = global[FOO_KEY]; +``` + +上面代码中,可以保证`global[FOO_KEY]`不会被其他脚本改写。 + ## 内置的Symbol值 除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。