Skip to content

Commit

Permalink
Merge pull request #2 from 17koa/master
Browse files Browse the repository at this point in the history
update
  • Loading branch information
zysam committed Mar 13, 2016
2 parents 32d9b28 + 758b049 commit 667b31b
Show file tree
Hide file tree
Showing 13 changed files with 658 additions and 20 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ koa是下一代基于nodejs的modern web framework,会用到很多es高级特

鉴于目前学习资料不多,故有此书

年前几天比较忙,更新暂缓

## 宗旨

大家一起学习koa
Expand Down
3 changes: 3 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Summary

* [Introduction](README.md)
* [Nodejs 4.x新特性](node4/README.md)
* [classes](node4/classes.md)
* [typed arrays](node4/typed_arrays.md)
* [generators](node4/generators.md)
* [collections](node4/collections.md)
* [Set](node4/ji_he.md)
* [Map](node4/map.md)
* [arrow functions](node4/arrow_functions.md)
* [block scoping](node4/block_scoping.md)
* [template strings](node4/template_strings.md)
Expand Down
3 changes: 3 additions & 0 deletions deleteTag.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
git checkout master
git branch -D %1
git push origin --delete %1
2 changes: 2 additions & 0 deletions mergeUpstream.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
git fetch upstream
git merge upstream/master
104 changes: 102 additions & 2 deletions node4/block_scoping.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,103 @@
# block scoping
# Let命令
## 定义Let变量
在ES6中引入了let命令,通过let命令定义的变量只能在let命令所在的代码块内部被引用。
```javascript
"use strict"
{
let hello = "Hello World!"
}
console.log(hello) //会报错,因为没有全局的hello变量被定义
```
从上面的例子可以看出,使用Let命令定义的变量不会自动被提升为全局变量。相反的情况,如果在上面的例子中,你使用var来定义hello这个变量,那么hello这个变量将自动被提升为全局变量,就可以被后面的console.log访问了。
## 变量死区
ES6中规定,如果你在一个代码区块中使用了let命令来定义变量,那么在变量被定义之前,不允许对这个变量的访问存在。因此在let命令之前的所有代码被称为变量死区。如果在变量死区发生了对变量的引用,那么JavaScript引擎将报错。
```javascript
"use strict"
{
console.log(hello); //将报错,因为变量声明在之后
let hello = "Hello World!";
}

使用 let 、const 作用域,块辖域
#正确代码
{
let hello = "Hello World!";
console.log(hello);
}
```
## 不能重复声明变量
在同一个代码区块中,你不能使用let/var命令重复定义一个已经已经存在的变量。因此下面的代码将报错。
```javascript
"use strict"
{
let hello = "Hello World!";
let hello = "Hello Not World!";//报错
console.log(hello);
}
{
let hello = "Hello World!";
var hello = "Hello Not World!";//报错
console.log(hello);
}
```
## 块级作用域
ES6引入let命令的一个副作用就是引入了块级作用域。让我们来看一个具体的例子来详细分析块级作用域。
```javascript
function f() { console.log('I am outside!'); }
(function () {
if(false) {
// 重复声明一次函数f
function f() { console.log('I am inside!'); }
}

f();
}());
```
在ES5环境中,这段代码将输出"I am inside!",这个是因为在ES5中,不管代码块是否被运行,函数定义都将自动被提升到外部(全局空间)。但是如果在ES6中运行,你将看到输出"I am outside!",这个是因为重复的function定义是在另外一个不被执行的代码块中。实际上在ES6中,上面的代码被翻译成了下面的ES5代码。
```javascript
"use strict";

function sayHello() {
console.log("say hello from global");
}

(function () {
if (false) {
var _sayHello = function _sayHello() {
console.log("say hello from inside");
};
}

sayHello();
})();
```
块级作用域的另外一个影响就是把变量绑定到了当前的作用域
```javascript
"use strict";
function hello() {
let word = "hello world!";
if (false) {
let word = "hello world1!";
}
console.log(word);
}

hello();//will see "Hello World!"
```
# const命令
const命令和let命令唯一的区别在于constant命令定义的是一个常量。因此使用constant命令定义的常量必须在定义的同时被初始化。
# 引入其他js文件中定义的变量/常量
在ES6中,可以使用import语句来引入其他文件中定义的常量 / 变量。
```javascript
"use strict"
//定义在constants.js的常量
export const HELLO = "hello"

//在其他js中
import * as constants from "./constants.js"
console.log(constants.HELLO)

import {HELLO as myHello} from "./constants.js"
console.log(myHello)
```
# 全局变量的属性
在ES6中,使用var定义的变量将是全局变量的属性(window --- 在browser中 or global--在server段代码中 ),因此可以通过window.<var_name>或者global.<var_name>来访问。但是在顶层代码中使用let / constant定义的变量/常量将不是全局变量的属性。
30 changes: 20 additions & 10 deletions node4/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,30 @@ class Polygon{
```
## 给class增加成员属性
在ES6中, 你可以通过getter和setter方法,给类增加属性。如果属性只有getter方法,那么它就是一个只读属性;如果属性同时又setter和getter方法,那么它就是一个可读写属性。请看下面的例子
**注意属性`name``_name`**
因为我们定义了 name 的读写器,而没有定义 _name 的读写器,所以访问这两个属性的结果是不同的。
```javascript
class Polygon{
constructor(height, width){
this.height = height;
this.width = width;
class Person{
constructor(name){
this._name = name;
}
get name(){
return this.name;
return this._name.toUpperCase();
}
/**
* 注意一点,不要这样写:
* set name(somename) {
* this.name = somename;
* }
* 因为给 this.name 赋值的时候会调用 set name ,这样会导致无限递归直到栈溢出。
*
*/
set name(somename){
this.name = somename;
this._name = somename;
}
}
```
```

## 给class增加成员函数
这点没什么可说的,就是在类定义中增加函数定义即可,请看下面的例
```javascript
Expand All @@ -47,10 +57,10 @@ class Polygon{
this.width = width;
}
get name(){
return this.name;
return this._name;
}
set name(somename){
this.name = somename;
this._name = somename;
}

//readonly property
Expand All @@ -64,7 +74,7 @@ class Polygon{
}
```
## 实现class的继承
在ES6中,通过使用extends关键字,你可以使用累的继承
在ES6中,通过使用extends关键字,你可以使用类的继承
```javascript
class Animal{
constructor(name){
Expand Down
4 changes: 1 addition & 3 deletions node4/collections.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# collections

集合、映射、弱集合、弱映射
在这个章节中,我们将介绍ES6中引入的集合对象和映射对象。因为涉及的内容比较多,所以我们将分成2个部分,分别对集合和映射对象进行介绍。
105 changes: 105 additions & 0 deletions node4/ji_he.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# 集合
集合对象类似于以前JavaScript中的数组,只是集合对象中不能存在相同的对象。
## 集合的初始化
集合对象是通过构造函数进行初始化的,调用格式有2种
* 不传参数给构造函数,这将创建一个空的集合对象
```javascript
var sampleSet = new Set();
console.log(sampleSet.size); //will output 0
```
* 传递一个数组对象给构造函数,将创建一个包含这个数组中不重复内容的集合
```javascript
var sampleSet = new Set([1,2,3,4,5,5,6]);
console.log(sampleSet.size);//will output 6
console.log(sampleSet);//will ouput Set {1,2,3,4,5,6}
```

## 向集合添加内容
可以通过使用集合对象的add方法向已经创建的集合添加新的内容
```javascript
var sampleSet = new Set();
sampleSet.add(2);
sampleSet.add('2');
console.log(sampleSet.size); //will output 2
console.log(sampleSet); //will output Set { 2, '2' }

//例子2
var sampleSet = new Set();
sampleSet.add(NaN);
sampleSet.add(NaN);
console.log(sampleSet); //will output Set { NaN }
```
从上面程序的输出,可以看出
* 集合可以保存不同类型的数据
* 在向集合添加数据的时候,JavaScript并不进行数据转化。因此2和'2'是不一样的
* 对集合对象来说,所有的NaN都是一样的

## 向集合添加对象
我们之所以将向集合添加对象单独出来解释,是因为对对象是否相同的判断和普通对象不一样。下面是几个例子。
```javascript
//例子1
var sampleSet = new Set();
var a = {};
var a1 = a;
//因为a和a1在底层指向的是同一个内存对象,所以a === a1
sampleSet.add(a);
sampleSet.add(a1);
console.log(sampleSet); //will output Set { {} }

//例子2
var sampleSet = new Set();
var a = {};
var a1 = {};
//因为a和a1在底层指向的是不同的内存对象,所以a != a1
sampleSet.add(a);
sampleSet.add(a1);
console.log(sampleSet); //will output Set Set { {}, {} }
```

## 集合的其他操作
除了向已经存在的集合添加内容,你还可以通过集合的成员函数实施下面的操作
* 删除内容,通过```delete(value)```来删除集合中的某个内容
* 判断集合是否包含内容,通过```has(value)```来判断集合中是否包含参数所指定的内容
* 清除所有内容,通过```clear()```你可以删除一个集合中的所有内容

## 集合对象的遍历
遍历集合对象最简单的方法就是遍历```values()```方法的返回值,下面是一个具体的例子
```javascript
'use strict';
var sampleSet = new Set([1,2,3,4,5]);
//output is
//1
//2
//3
//4
//5
for (let val of sampleSet.values()){
console.log(val);
}
```
遍历集合的第二个方法是条用```forEach```函数完成,下面是具体的例子。对于这个例子,大家一定很奇怪,为什么forEach接受的函数的参数是2个。对于这点我一开始也觉得很奇怪,在看了相关的文档才明白,实际上对于集合中的每个元素,都有2个属性与之绑定(Key和value),只不过他们完全相同而已,我个人估计是为了和映射对象保持类似的结构,从而简化Javascript引擎而这么做的。
```javascript
var sampleSet = new Set([1,2,3,4,5]);
//output is
//1
//2
//3
//4
//5
//实际上你用console.log(key)也会得到完全一样的结果
sampleSet.forEach((value, key) => {console.log(value);});
```
# 弱集合
弱集合对象和普通的集合对象有着下面这些不同点:
* 弱集合对象只能保存对象,不能保存普通数据
* 弱集合对象对另外一个对象的引用,并不影响垃圾回收器的工作。换句话说,如果一个弱集合```set```包含一个对象```a```的引用,如果在运行过程中,除了这个应用,没有任何其他地方应用```a```这个对象了,那么垃圾回收器将回收```a```
* 弱集合对象没有```size```属性,也不能进行遍历。不能进行遍历的原因就是因为第二点。因为在遍历的过程中,集合中的对象随时可能被垃圾回收器给回收。

## 可以执行的操作
根据上面的描述,对弱集合对象可以进行的操作仅限于。
* 增加成员,使用```add()```方法增加成员
* 删除成员, 使用```delete()```方法删除成员
* 判断成员是否在集合,使用```has()```方法判断一个成员是否存在

## 弱集合的使用
弱集合的一个使用场合是你需要操作DOM的一个集合,但是你不想因为集合拥有对DOM对象的引用而阻止对DOM对象的自动销毁。
75 changes: 75 additions & 0 deletions node4/map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 映射
我们可以把映射看成是对JavaScript Object的一个扩展。在传统的JavaScript Object中,当我们设置key, value对的时候,key只能是字符串。ES6对这个进行了扩展,形成了新的映射类型,映射类型的key, value对可以是任意对象。

## 映射的初始化
在ES6中,可以通过如下2种对构造函数的调用来创建并初始化一个映射对象
* 不传参数给构造函数,这将创建一个空的映射
```javascript
var sampleMap = new Map();
console.log(sampleMap.size); //will output 0
```
* 传一个数组给构造函数,这个传入的数组的每个元素包含2个值,第一个将作为key, 另外一个作为value
```javascript
var sampleMap = new Map([['key1', 'val1'], ['key2', 'val2']]);
//will output 2, also sampleMap will have key key1 and key2
console.log(sampleMap.size);//will output 2
```

## 对映射对象的操作
和集合对象类似,你可以对映射对象执行如下的操作
* 增加成员,通过```set(key, val)```向映射对象增加成员
* 删除成员,通过```delete(key)```从映射对象删除成员
* 测试是否包含,通过```has(key)```测试是否包含某个key
* 获取成员,通过```get(key)```返回成员
* 清空成员,通过```clear()```操作清空整个映射对象

另外,映射对象和集合对象一样,当你使用object作为key的时候,是根据key是否指向同样的内存对象来判断是否new一个key的。如果2个key的对象指向的是同一个内存对象,那么后面一个set将覆盖前面一个set的内容。

## 对映射对象的遍历
对映射对象,你可以使用下面的任意一种方法进行合适的遍历。
* ```keys()```调用,```keys()```调用将返回映射对象key的集合,接着你就可以使用```for...of```循环遍历了。
```javascript
'use strict';
var sampleMap = new Map();
sampleMap.set('key1', 'val1');
sampleMap.set('key2', 'val2');
for (let key of sampleMap.keys()){
console.log(key + '---' + sampleMap.get(key));
}
```

* ```values()```调用,```values()```调用返回映射对象value的集合,接着你就可以使用```for...of```循环遍历了。
```javascript
'use strict';
var sampleMap = new Map();
sampleMap.set('key1', 'val1');
sampleMap.set('key2', 'val2');
for (let val of sampleMap.values()){
console.log(val);
}
```

* ```entries()```调用,```entries()```调用返回映射对象key和value的集合,接着你就可以使用```for...of```循环遍历了。
```javascript
'use strict';
var sampleMap = new Map();
sampleMap.set('key1', 'val1');
sampleMap.set('key2', 'val2');
for (let item of sampleMap.entries()){
console.log(item[0] + '---' + item[1]);
}
```

*```forEach()```调用
```javascript
'use strict';
var sampleMap = new Map();
sampleMap.set('key1', 'val1');
sampleMap.set('key2', 'val2');
sampleMap.forEach(function(value, key, map){
console.log(key + '---' + value);
});
```

# 弱映射
和弱集合一样,弱映射的key不被垃圾回收所检查,当key对应的对象被回收的时候,也自动从弱映射中被删除。由于这个原因,弱映射和弱集合一样无法进行遍历,这能修改。
Binary file added node4/promise_lifecycle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 667b31b

Please sign in to comment.