<script>alert("abc")</script> has sent you a message.
``` - 标签模板的另一个应用,就是多语言转换(国际化处理)。 ```javascript @@ -793,7 +791,7 @@ i18n`Welcome to ${siteName}, you are visitor number ${visitorNumber}!` // "欢迎访问xxx,您是第xxxx位访问者!" ``` -模板字符串本身并不能取代Mustache之类的模板库,因为没有条件判断和循环处理功能,但是通过标签函数,你可以自己添加这些功能。 +模板字符串本身并不能取代 Mustache 之类的模板库,因为没有条件判断和循环处理功能,但是通过标签函数,你可以自己添加这些功能。 ```javascript // 下面的hashTemplate函数 @@ -807,7 +805,7 @@ let libraryHtml = hashTemplate` `; ``` -除此之外,你甚至可以使用标签模板,在JavaScript语言之中嵌入其他语言。 +除此之外,你甚至可以使用标签模板,在 JavaScript 语言之中嵌入其他语言。 ```javascript jsx` @@ -821,9 +819,9 @@ jsx` ` ``` -上面的代码通过`jsx`函数,将一个DOM字符串转为React对象。你可以在Github找到`jsx`函数的[具体实现](https://gist.github.com/lygaret/a68220defa69174bdec5)。 +上面的代码通过`jsx`函数,将一个 DOM 字符串转为 React 对象。你可以在 Github 找到`jsx`函数的[具体实现](https://gist.github.com/lygaret/a68220defa69174bdec5)。 -下面则是一个假想的例子,通过`java`函数,在JavaScript代码之中运行Java代码。 +下面则是一个假想的例子,通过`java`函数,在 JavaScript 代码之中运行 Java 代码。 ```javascript java` @@ -857,11 +855,11 @@ function tag(strings) { } ``` -上面代码中,`tag`函数的第一个参数`strings`,有一个`raw`属性,也指向一个数组。该数组的成员与`strings`数组完全一致。比如,`strings`数组是`["First line\nSecond line"]`,那么`strings.raw`数组就是`["First line\\nSecond line"]`。两者唯一的区别,就是字符串里面的斜杠都被转义了。比如,strings.raw数组会将`\n`视为`\\`和`n`两个字符,而不是换行符。这是为了方便取得转义之前的原始模板而设计的。 +上面代码中,`tag`函数的第一个参数`strings`,有一个`raw`属性,也指向一个数组。该数组的成员与`strings`数组完全一致。比如,`strings`数组是`["First line\nSecond line"]`,那么`strings.raw`数组就是`["First line\\nSecond line"]`。两者唯一的区别,就是字符串里面的斜杠都被转义了。比如,strings.raw 数组会将`\n`视为`\\`和`n`两个字符,而不是换行符。这是为了方便取得转义之前的原始模板而设计的。 ## String.raw() -ES6还为原生的String对象,提供了一个`raw`方法。 +ES6 还为原生的 String 对象,提供了一个`raw`方法。 `String.raw`方法,往往用来充当模板字符串的处理函数,返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,对应于替换变量后的模板字符串。 @@ -941,11 +939,10 @@ function tag(strs) { tag`\unicode and \u{55}` ``` -上面代码中,模板字符串原本是应该报错的,但是由于放松了对字符串转义的限制,所以不报错了,JavaScript引擎将第一个字符设置为`undefined`,但是`raw`属性依然可以得到原始字符串,因此`tag`函数还是可以对原字符串进行处理。 +上面代码中,模板字符串原本是应该报错的,但是由于放松了对字符串转义的限制,所以不报错了,JavaScript 引擎将第一个字符设置为`undefined`,但是`raw`属性依然可以得到原始字符串,因此`tag`函数还是可以对原字符串进行处理。 注意,这种对字符串转义的放松,只在标签模板解析字符串时生效,不是标签模板的场合,依然会报错。 ```javascript let bad = `bad escape sequence: \unicode`; // 报错 ``` - diff --git a/docs/style.md b/docs/style.md index 52625a3..375377c 100644 --- a/docs/style.md +++ b/docs/style.md @@ -234,7 +234,7 @@ for (i = 0; i < len; i++) { const itemsCopy = [...items]; ``` -使用Array.from方法,将类似数组的对象转为数组。 +使用 Array.from 方法,将类似数组的对象转为数组。 ```javascript const foo = document.querySelectorAll('.foo'); @@ -251,7 +251,7 @@ const nodes = Array.from(foo); })(); ``` -那些需要使用函数表达式的场合,尽量用箭头函数代替。因为这样更简洁,而且绑定了this。 +那些需要使用函数表达式的场合,尽量用箭头函数代替。因为这样更简洁,而且绑定了 this。 ```javascript // bad @@ -268,7 +268,7 @@ const nodes = Array.from(foo); [1, 2, 3].map(x => x * x); ``` -箭头函数取代`Function.prototype.bind`,不应再用self/\_this/that绑定 this。 +箭头函数取代`Function.prototype.bind`,不应再用 self/\_this/that 绑定 this。 ```javascript // bad @@ -298,7 +298,7 @@ function divide(a, b, { option = false } = {}) { } ``` -不要在函数体内使用arguments变量,使用rest运算符(...)代替。因为rest运算符显式表明你想要获取参数,而且arguments是一个类似数组的对象,而rest运算符可以提供一个真正的数组。 +不要在函数体内使用 arguments 变量,使用 rest 运算符(...)代替。因为 rest 运算符显式表明你想要获取参数,而且 arguments 是一个类似数组的对象,而 rest 运算符可以提供一个真正的数组。 ```javascript // bad @@ -327,9 +327,9 @@ function handleThings(opts = {}) { } ``` -## Map结构 +## Map 结构 -注意区分Object和Map,只有模拟现实世界的实体对象时,才使用Object。如果只是需要`key: value`的数据结构,使用Map结构。因为Map有内建的遍历机制。 +注意区分 Object 和 Map,只有模拟现实世界的实体对象时,才使用 Object。如果只是需要`key: value`的数据结构,使用 Map 结构。因为 Map 有内建的遍历机制。 ```javascript let map = new Map(arr); @@ -349,7 +349,7 @@ for (let item of map.entries()) { ## Class -总是用Class,取代需要prototype的操作。因为Class的写法更简洁,更易于理解。 +总是用 Class,取代需要 prototype 的操作。因为 Class 的写法更简洁,更易于理解。 ```javascript // bad @@ -398,7 +398,7 @@ class PeekableQueue extends Queue { ## 模块 -首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用`import`取代`require`。 +首先,Module 语法是 JavaScript 模块的标准写法,坚持使用这种写法。使用`import`取代`require`。 ```javascript // bad @@ -468,7 +468,7 @@ const StyleGuide = { export default StyleGuide; ``` -## ESLint的使用 +## ESLint 的使用 ESLint 是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。 @@ -485,7 +485,7 @@ $ npm i -g eslint-config-airbnb $ npm i -g eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react ``` -最后,在项目的根目录下新建一个`.eslintrc`文件,配置ESLint。 +最后,在项目的根目录下新建一个`.eslintrc`文件,配置 ESLint。 ```javascript { @@ -522,4 +522,4 @@ index.js ✖ 5 problems (5 errors, 0 warnings) ``` -上面代码说明,原文件有五个错误,其中两个是不应该使用`var`命令,而要使用`let`或`const`;一个是定义了变量,却没有使用;另外两个是行首缩进为4个空格,而不是规定的2个空格。 +上面代码说明,原文件有五个错误,其中两个是不应该使用`var`命令,而要使用`let`或`const`;一个是定义了变量,却没有使用;另外两个是行首缩进为 4 个空格,而不是规定的 2 个空格。 diff --git a/docs/symbol.md b/docs/symbol.md index 7e2b351..11c5384 100644 --- a/docs/symbol.md +++ b/docs/symbol.md @@ -247,7 +247,7 @@ const shapeType = { }; ``` -上面代码中,除了将`shapeType.triangle`的值设为一个Symbol,其他地方都不用修改。 +上面代码中,除了将`shapeType.triangle`的值设为一个 Symbol,其他地方都不用修改。 ## 属性名的遍历 @@ -293,7 +293,7 @@ Object.getOwnPropertySymbols(obj) 上面代码中,使用`Object.getOwnPropertyNames`方法得不到`Symbol`属性名,需要使用`Object.getOwnPropertySymbols`方法。 -另一个新的API,`Reflect.ownKeys`方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。 +另一个新的 API,`Reflect.ownKeys`方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。 ```javascript let obj = { @@ -341,7 +341,7 @@ Object.getOwnPropertySymbols(x) // [Symbol(size)] ## Symbol.for(),Symbol.keyFor() -有时,我们希望重新使用同一个 Symbol 值,`Symbol.for`方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。 +有时,我们希望重新使用同一个 Symbol 值,`Symbol.for`方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。 ```javascript let s1 = Symbol.for('foo'); @@ -352,7 +352,7 @@ s1 === s2 // true 上面代码中,`s1`和`s2`都是 Symbol 值,但是它们都是同样参数的`Symbol.for`方法生成的,所以实际上是同一个值。 -`Symbol.for()`与`Symbol()`这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。`Symbol.for()`不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的`key`是否已经存在,如果不存在才会新建一个值。比如,如果你调用`Symbol.for("cat")`30次,每次都会返回同一个 Symbol 值,但是调用`Symbol("cat")`30次,会返回30个不同的 Symbol 值。 +`Symbol.for()`与`Symbol()`这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。`Symbol.for()`不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的`key`是否已经存在,如果不存在才会新建一个值。比如,如果你调用`Symbol.for("cat")`30 次,每次都会返回同一个 Symbol 值,但是调用`Symbol("cat")`30 次,会返回 30 个不同的 Symbol 值。 ```javascript Symbol.for("bar") === Symbol.for("bar") @@ -391,9 +391,9 @@ iframe.contentWindow.Symbol.for('foo') === Symbol.for('foo') ## 实例:模块的 Singleton 模式 -Singleton模式指的是调用一个类,任何时候返回的都是同一个实例。 +Singleton 模式指的是调用一个类,任何时候返回的都是同一个实例。 -对于Node来说,模块文件可以看成是一个类。怎么保证每次执行这个模块文件,返回的都是同一个实例呢? +对于 Node 来说,模块文件可以看成是一个类。怎么保证每次执行这个模块文件,返回的都是同一个实例呢? 很容易想到,可以把实例放到顶层对象`global`。 @@ -428,7 +428,7 @@ global._foo = 123; 上面的代码,会使得别的脚本加载`mod.js`都失真。 -为了防止这种情况出现,我们就可以使用Symbol。 +为了防止这种情况出现,我们就可以使用 Symbol。 ```javascript // mod.js @@ -461,11 +461,11 @@ const FOO_KEY = Symbol('foo'); // 后面代码相同 …… ``` -上面代码将导致其他脚本都无法引用`FOO_KEY`。但这样也有一个问题,就是如果多次执行这个脚本,每次得到的`FOO_KEY`都是不一样的。虽然Node会将脚本的执行结果缓存,一般情况下,不会多次执行同一个脚本,但是用户可以手动清除缓存,所以也不是完全可靠。 +上面代码将导致其他脚本都无法引用`FOO_KEY`。但这样也有一个问题,就是如果多次执行这个脚本,每次得到的`FOO_KEY`都是不一样的。虽然 Node 会将脚本的执行结果缓存,一般情况下,不会多次执行同一个脚本,但是用户可以手动清除缓存,所以也不是完全可靠。 -## 内置的Symbol值 +## 内置的 Symbol 值 -除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。 +除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。 ### Symbol.hasInstance @@ -712,7 +712,7 @@ myIterable[Symbol.iterator] = function* () { [...myIterable] // [1, 2, 3] ``` -对象进行`for...of`循环时,会调用`Symbol.iterator`方法,返回该对象的默认遍历器,详细介绍参见《Iterator和for...of循环》一章。 +对象进行`for...of`循环时,会调用`Symbol.iterator`方法,返回该对象的默认遍历器,详细介绍参见《Iterator 和 for...of 循环》一章。 ```javascript class Collection { @@ -787,11 +787,11 @@ let x = new Collection(); Object.prototype.toString.call(x) // "[object xxx]" ``` -ES6新增内置对象的`Symbol.toStringTag`属性值如下。 +ES6 新增内置对象的`Symbol.toStringTag`属性值如下。 - `JSON[Symbol.toStringTag]`:'JSON' - `Math[Symbol.toStringTag]`:'Math' -- Module对象`M[Symbol.toStringTag]`:'Module' +- Module 对象`M[Symbol.toStringTag]`:'Module' - `ArrayBuffer.prototype[Symbol.toStringTag]`:'ArrayBuffer' - `DataView.prototype[Symbol.toStringTag]`:'DataView' - `Map.prototype[Symbol.toStringTag]`:'Map' @@ -827,7 +827,7 @@ Object.keys(Array.prototype[Symbol.unscopables]) // ['copyWithin', 'entries', 'fill', 'find', 'findIndex', 'includes', 'keys'] ``` -上面代码说明,数组有7个属性,会被`with`命令排除。 +上面代码说明,数组有 7 个属性,会被`with`命令排除。 ```javascript // 没有 unscopables 时