mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-29 13:52:22 +00:00
edit module, array
This commit is contained in:
parent
6b1ee303ff
commit
9dcdc6a9e8
@ -182,7 +182,7 @@ for (let [index, elem] of ['a', 'b'].entries()) {
|
||||
|
||||
## 数组实例的includes()
|
||||
|
||||
Array.protypeto.includes方法返回一个布尔值,表示某个数组是否包含给定的值。该方法属于ES7。
|
||||
`Array.protypeto.includes`方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的`includes`方法类似。该方法属于ES7,但Babel转码器已经支持。
|
||||
|
||||
```javascript
|
||||
[1, 2, 3].includes(2); // true
|
||||
@ -190,13 +190,35 @@ Array.protypeto.includes方法返回一个布尔值,表示某个数组是否
|
||||
[1, 2, NaN].includes(NaN); // true
|
||||
```
|
||||
|
||||
该方法的第二个参数表示搜索的起始位置,默认为0。
|
||||
该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。
|
||||
|
||||
```javascript
|
||||
[1, 2, 3].includes(3, 3); // false
|
||||
[1, 2, 3].includes(3, -1); // true
|
||||
```
|
||||
|
||||
没有该方法之前,我们通常使用数组的`indexOf`方法,检查是否包含某个值。
|
||||
|
||||
```javascript
|
||||
if (arr.indexOf(el) !== -1) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
`indexOf`方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相当运算符(===)进行判断,这会导致对`NaN`的误判。
|
||||
|
||||
```javascript
|
||||
[NaN].indexOf(NaN)
|
||||
// -1
|
||||
```
|
||||
|
||||
`includes`使用的是不一样的判断算法,就没有这个问题。
|
||||
|
||||
```javascript
|
||||
[NaN].includes(NaN)
|
||||
// true
|
||||
```
|
||||
|
||||
下面代码用来检查当前环境是否支持该方法,如果不支持,部署一个简易的替代版本。
|
||||
|
||||
```javascript
|
||||
@ -208,6 +230,11 @@ const contains = (() =>
|
||||
contains(["foo", "bar"], "baz"); // => false
|
||||
```
|
||||
|
||||
另外,Map和Set数据结构有一个`has`方法,需要注意与`includes`区分。
|
||||
|
||||
- Map结构的`has`方法,是用来查找键名的,比如`Map.prototype.has(key)`、`WeakMap.prototype.has(key)`、`Reflect.has(target, propertyKey)`。
|
||||
- Set结构的`has`方法,是用来查找值的,比如`Set.prototype.has(value)`、`WeakSet.prototype.has(value)`。
|
||||
|
||||
## 数组推导
|
||||
|
||||
数组推导(array comprehension)提供简洁写法,允许直接通过现有数组生成新数组。这项功能本来是要放入ES6的,但是TC39委员会想继续完善这项功能,让其支持所有数据结构(内部调用iterator对象),不像现在只支持数组,所以就把它推迟到了ES7。Babel转码器已经支持这个功能。
|
||||
|
@ -20,11 +20,13 @@ import { stat, exists, readFile } from 'fs';
|
||||
|
||||
所以,ES6可以在编译时就完成模块编译,效率要比CommonJS模块高。
|
||||
|
||||
需要注意的是,ES6的模块自动采用严格模块,不管你有没有在模块头部加上`"use strict"`。
|
||||
|
||||
## export命令
|
||||
|
||||
模块功能主要由两个命令构成:export和import。export命令用于用户自定义模块,规定对外接口;import命令用于输入其他模块提供的功能,同时创造命名空间(namespace),防止函数名冲突。
|
||||
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
|
||||
|
||||
ES6允许将独立的JS文件作为模块,也就是说,允许一个JavaScript脚本文件调用另一个脚本文件。该文件内部的所有变量,外部无法获取,必须使用export关键字输出变量。下面是一个JS文件,里面使用export命令输出变量。
|
||||
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个JS文件,里面使用export命令输出变量。
|
||||
|
||||
```javascript
|
||||
// profile.js
|
||||
@ -58,6 +60,23 @@ export function multiply (x, y) {
|
||||
|
||||
上面代码对外输出一个函数multiply。
|
||||
|
||||
通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名。
|
||||
|
||||
```javascript
|
||||
function v1() { ... }
|
||||
function v2() { ... }
|
||||
|
||||
export {
|
||||
v1 as streamV1,
|
||||
v2 as streamV2,
|
||||
v2 as streamLatestVersion
|
||||
};
|
||||
```
|
||||
|
||||
上面代码使用as关键字,重命名了函数v1和v2的对外接口。重命名后,v2可以用不同的名字输出两次。
|
||||
|
||||
最后,export命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,下面的import命令也是如此。
|
||||
|
||||
## import命令
|
||||
|
||||
使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块(文件)。
|
||||
@ -72,9 +91,9 @@ function setName(element) {
|
||||
}
|
||||
```
|
||||
|
||||
上面代码属于另一个文件main.js,import命令就用于加载profile.js文件,并从中输入变量。import命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。
|
||||
上面代码的import命令,就用于加载profile.js文件,并从中输入变量。import命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。
|
||||
|
||||
如果想为输入的变量重新取一个名字,import语句中要使用as关键字,将输入的变量重命名。
|
||||
如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。
|
||||
|
||||
```javascript
|
||||
import { lastName as surname } from './profile';
|
||||
@ -129,7 +148,7 @@ export function circumference(radius) {
|
||||
```javascript
|
||||
// main.js
|
||||
|
||||
import { area, circumference } from 'circle';
|
||||
import { area, circumference } from './circle';
|
||||
|
||||
console.log("圆面积:" + area(4));
|
||||
console.log("圆周长:" + circumference(14));
|
||||
@ -138,7 +157,7 @@ console.log("圆周长:" + circumference(14));
|
||||
上面写法是逐一指定要输入的方法。另一种写法是整体输入。
|
||||
|
||||
```javascript
|
||||
import * as circle from 'circle';
|
||||
import * as circle from './circle';
|
||||
|
||||
console.log("圆面积:" + circle.area(4));
|
||||
console.log("圆周长:" + circle.circumference(14));
|
||||
@ -151,7 +170,7 @@ module命令可以取代import语句,达到整体输入模块的作用。
|
||||
```javascript
|
||||
// main.js
|
||||
|
||||
module circle from 'circle';
|
||||
module circle from './circle';
|
||||
|
||||
console.log("圆面积:" + circle.area(4));
|
||||
console.log("圆周长:" + circle.circumference(14));
|
||||
@ -161,7 +180,7 @@ module命令后面跟一个变量,表示输入的模块定义在该变量上
|
||||
|
||||
## export default命令
|
||||
|
||||
从前面的例子可以看出,使用import的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
|
||||
从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
|
||||
|
||||
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到`export default`命令,为模块指定默认输出。
|
||||
|
||||
@ -182,7 +201,7 @@ import customName from './export-default';
|
||||
customName(); // 'foo'
|
||||
```
|
||||
|
||||
上面代码的import命令,可以用任意名称指向`export-default.js`输出的方法。需要注意的是,这时import命令后面,不使用大括号。
|
||||
上面代码的import命令,可以用任意名称指向`export-default.js`输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面,不使用大括号。
|
||||
|
||||
export default命令用在非匿名函数前,也是可以的。
|
||||
|
||||
@ -226,8 +245,16 @@ export function crc32(){};
|
||||
export default function (x, y) {
|
||||
return x * y;
|
||||
};
|
||||
|
||||
// 或者
|
||||
|
||||
function add(x, y) {
|
||||
return x * y;
|
||||
};
|
||||
export {add as default};
|
||||
|
||||
// app.js
|
||||
import { default } from 'modules';
|
||||
import { default as xxx } from 'modules';
|
||||
```
|
||||
|
||||
有了`export default`命令,输入模块时就非常直观了,以输入jQuery模块为例。
|
||||
|
@ -430,3 +430,24 @@ ES6新增了6个三角函数方法。
|
||||
- Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)
|
||||
- Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)
|
||||
- Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)
|
||||
|
||||
## 指数运算符
|
||||
|
||||
ES7新增了一个指数运算符(`**`),目前Babel转码器已经支持。
|
||||
|
||||
```javascript
|
||||
2 ** 2 // 4
|
||||
2 ** 3 // 8
|
||||
```
|
||||
|
||||
指数运算符可以与等号结合,形成一个新的赋值运算符(`**=`)。
|
||||
|
||||
```javascript
|
||||
let a = 2;
|
||||
a **= 2;
|
||||
// 等同于 a = a * a;
|
||||
|
||||
let b = 3;
|
||||
b **= 3;
|
||||
// 等同于 b = b * b * b;
|
||||
```
|
||||
|
@ -26,26 +26,15 @@
|
||||
- Benjamin De Cock, [Frontend Guidelines](https://github.com/bendc/frontend-guidelines): ES6最佳实践
|
||||
- Jani Hartikainen, [ES6: What are the benefits of the new features in practice?](http://codeutopia.net/blog/2015/01/06/es6-what-are-the-benefits-of-the-new-features-in-practice/)
|
||||
|
||||
## 语法点
|
||||
## let和const
|
||||
|
||||
- Kyle Simpson, [For and against let](http://davidwalsh.name/for-and-against-let): 讨论let命令的作用域
|
||||
- kangax, [Why typeof is no longer “safe”](http://es-discourse.com/t/why-typeof-is-no-longer-safe/15): 讨论在块级作用域内,let命令的变量声明和赋值的行为
|
||||
- Axel Rauschmayer, [Variables and scoping in ECMAScript 6](http://www.2ality.com/2015/02/es6-scoping.html): 讨论块级作用域与let和const的行为
|
||||
|
||||
## 解构赋值
|
||||
|
||||
- Nick Fitzgerald, [Destructuring Assignment in ECMAScript 6](http://fitzgeraldnick.com/weblog/50/): 详细介绍解构赋值的用法
|
||||
- Nicholas C. Zakas, [Understanding ECMAScript 6 arrow functions](http://www.nczonline.net/blog/2013/09/10/understanding-ecmascript-6-arrow-functions/)
|
||||
- Jack Franklin, [Real Life ES6 - Arrow Functions](http://javascriptplayground.com/blog/2014/04/real-life-es6-arrow-fn/)
|
||||
- Axel Rauschmayer, [Handling required parameters in ECMAScript 6](http://www.2ality.com/2014/04/required-parameters-es6.html)
|
||||
- Axel Rauschmayer, [ECMAScript 6’s new array methods](http://www.2ality.com/2014/05/es6-array-methods.html): 对ES6新增的数组方法的全面介绍
|
||||
- Dmitry Soshnikov, [ES6 Notes: Default values of parameters](http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/): 介绍参数的默认值
|
||||
- Ragan Wald, [Destructuring and Recursion in ES6](http://raganwald.com/2015/02/02/destructuring.html): rest参数和扩展运算符的详细介绍
|
||||
|
||||
## Collections
|
||||
|
||||
- Mozilla Developer Network, [WeakSet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet):介绍WeakSet数据结构
|
||||
- Dwayne Charrington, [What Are Weakmaps In ES6?](http://ilikekillnerds.com/2015/02/what-are-weakmaps-in-es6/): WeakMap数据结构介绍
|
||||
- Axel Rauschmayer, [ECMAScript 6: maps and sets](http://www.2ality.com/2015/01/es6-maps-sets.html): Set和Map结构的详细介绍
|
||||
- Jason Orendorff, [ES6 In Depth: Collections](https://hacks.mozilla.org/2015/06/es6-in-depth-collections/):Set和Map结构的设计思想
|
||||
- Axel Rauschmayer, [Converting ES6 Maps to and from JSON](http://www.2ality.com/2015/08/es6-map-json.html): 如何将Map与其他数据结构互相转换
|
||||
|
||||
## 字符串
|
||||
|
||||
@ -59,6 +48,19 @@
|
||||
- Mathias Bynens, [Unicode-aware regular expressions in ES6](https://mathiasbynens.be/notes/es6-unicode-regex): 详细介绍正则表达式的u修饰符
|
||||
- Axel Rauschmayer, [New regular expression features in ECMAScript 6](http://www.2ality.com/2015/07/regexp-es6.html):ES6正则特性的详细介绍
|
||||
|
||||
## 数组
|
||||
|
||||
- Axel Rauschmayer, [ECMAScript 6’s new array methods](http://www.2ality.com/2014/05/es6-array-methods.html): 对ES6新增的数组方法的全面介绍
|
||||
- TC39, [Array.prototype.includes](https://github.com/tc39/Array.prototype.includes/): 数组的includes方法的规格
|
||||
|
||||
## 函数
|
||||
|
||||
- Nicholas C. Zakas, [Understanding ECMAScript 6 arrow functions](http://www.nczonline.net/blog/2013/09/10/understanding-ecmascript-6-arrow-functions/)
|
||||
- Jack Franklin, [Real Life ES6 - Arrow Functions](http://javascriptplayground.com/blog/2014/04/real-life-es6-arrow-fn/)
|
||||
- Axel Rauschmayer, [Handling required parameters in ECMAScript 6](http://www.2ality.com/2014/04/required-parameters-es6.html)
|
||||
- Dmitry Soshnikov, [ES6 Notes: Default values of parameters](http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/): 介绍参数的默认值
|
||||
- Ragan Wald, [Destructuring and Recursion in ES6](http://raganwald.com/2015/02/02/destructuring.html): rest参数和扩展运算符的详细介绍
|
||||
|
||||
## 对象
|
||||
|
||||
- Addy Osmani, [Data-binding Revolutions with Object.observe()](http://www.html5rocks.com/en/tutorials/es7/observe/): 介绍Object.observe()的概念
|
||||
@ -81,6 +83,14 @@
|
||||
- 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的深入介绍
|
||||
|
||||
## Set和Map
|
||||
|
||||
- Mozilla Developer Network, [WeakSet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet):介绍WeakSet数据结构
|
||||
- Dwayne Charrington, [What Are Weakmaps In ES6?](http://ilikekillnerds.com/2015/02/what-are-weakmaps-in-es6/): WeakMap数据结构介绍
|
||||
- Axel Rauschmayer, [ECMAScript 6: maps and sets](http://www.2ality.com/2015/01/es6-maps-sets.html): Set和Map结构的详细介绍
|
||||
- Jason Orendorff, [ES6 In Depth: Collections](https://hacks.mozilla.org/2015/06/es6-in-depth-collections/):Set和Map结构的设计思想
|
||||
- Axel Rauschmayer, [Converting ES6 Maps to and from JSON](http://www.2ality.com/2015/08/es6-map-json.html): 如何将Map与其他数据结构互相转换
|
||||
|
||||
## Iterator
|
||||
|
||||
- Mozilla Developer Network, [Iterators and generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators)
|
||||
@ -138,6 +148,7 @@
|
||||
- Jack Franklin, [JavaScript Modules the ES6 Way](http://24ways.org/2014/javascript-modules-the-es6-way/): ES6模块入门
|
||||
- Axel Rauschmayer, [ECMAScript 6 modules: the final syntax](http://www.2ality.com/2014/09/es6-modules-final.html): ES6模块的介绍,以及与CommonJS规格的详细比较
|
||||
- Dave Herman, [Static module resolution](http://calculist.org/blog/2012/06/29/static-module-resolution/): ES6模块的静态化设计思想
|
||||
- Jason Orendorff, [ES6 In Depth: Modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/): ES6模块设计思想的介绍
|
||||
|
||||
## 工具
|
||||
|
||||
|
@ -286,14 +286,14 @@ function authorize(user, action) {
|
||||
var x = 1;
|
||||
var y = 2;
|
||||
|
||||
console.log(`${x} + ${y} = ${x+y}`)
|
||||
`${x} + ${y} = ${x + y}`
|
||||
// "1 + 2 = 3"
|
||||
|
||||
console.log(`${x} + ${y*2} = ${x+y*2}`)
|
||||
`${x} + ${y * 2} = ${x + y * 2}`
|
||||
// "1 + 4 = 5"
|
||||
|
||||
var obj = {x: 1, y: 2};
|
||||
console.log(`${obj.x + obj.y}`)
|
||||
`${obj.x + obj.y}`
|
||||
// 3
|
||||
```
|
||||
|
||||
@ -304,7 +304,7 @@ function fn() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
console.log(`foo ${fn()} bar`);
|
||||
`foo ${fn()} bar`
|
||||
// foo Hello World bar
|
||||
```
|
||||
|
||||
@ -318,6 +318,13 @@ var msg = `Hello, ${place}`;
|
||||
// 报错
|
||||
```
|
||||
|
||||
由于模板字符串的大括号内部,就是执行JavaScript代码,因此如果表达式放在引号之中,将会原样输出。
|
||||
|
||||
```javascript
|
||||
`Hello ${'World'}`
|
||||
// "Hello World"
|
||||
```
|
||||
|
||||
## 标签模板
|
||||
|
||||
模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。
|
||||
|
Loading…
x
Reference in New Issue
Block a user