Skip to content

Commit

Permalink
把博客原文上传,防止丢失
Browse files Browse the repository at this point in the history
  • Loading branch information
TanYiBing committed Oct 17, 2018
0 parents commit 188ec56
Show file tree
Hide file tree
Showing 50 changed files with 4,026 additions and 0 deletions.
128 changes: 128 additions & 0 deletions ES6中的export-import.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
title: ES6中的export & import
date: 2018-10-07 23:44:24
tags:
- JavaScript
categories:
- JavaScript
---
上次说了一下[exports和module.exports的区别](http://tanyibing.com/2018/09/19/exports%E5%92%8Cmodule-exports%E7%9A%84%E5%8C%BA%E5%88%AB/),但是只讲了那一种状态,所以今天特意再来看看ES6中module的内容。

在ES6中,专门实现了模块化的功能。想要更仔细的阅读可以看一看阮一峰的《ESMAScript6入门》中的[Module的语法](http://es6.ruanyifeng.com/#docs/module)。里面是这么说的:

>在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
由此可见ES6中的模块化功能还是很强大的。

### export

先看几种export的写法:

// 第一种 输出两个变量
export var firstName = 'Michael';
export var lastName = 'Jackson';

// 第二种 和第一种一样,相同情况应该优先使用第二种。
var firstName = 'Michael';
var lastName = 'Jackson';
export {firstName, lastName, year};

// 第三种 输出函数或类
export function multiply(x, y) {
return x * y;
};

上面的三种情况在注释里解释了,就按这种模式写。但是要注意的是不要写成下面的样子;

// 报错
export 1;

// 报错
var m = 1;
export m;

这样写是直接输出,而不是通过接口,所以会报错。应该写成下面这样:

// 写法一
export var m = 1;

// 写法二
var m = 1;
export {m};

// 写法三
var n = 1;
export {n as m};

同样的,`function``class`也要按这种接口的方式去写:

// 报错
function f() {}
export f;

// 正确
export function f() {};

// 正确
function f() {}
export {f};

### import

看几个import的写法:

// 普通写法
import {firstName, lastName, year} from './profile.js';

// 重命名写法
import { lastName as surname } from './profile.js';

// 整体加载写法
import * as name from './profile.js';

这就是import的几种写法,不要妖来妖去的,例如使用表达式和变量、修改接口啊什么的操作,即使可以操作,也是极不推荐的,防止出现错误后找不到问题的根源。

### export default

`export default`是一种默认输出的方式,他的形式如下:

// 输出
export default function () {
console.log('foo');
}

// 输入
import customName from './export-default';
customName();

可以发现,**默认输出之后,引入时被当成匿名函数,我们可以给他起任意的名字。`export default`可以用在`非匿名函数`前面,但是在外部还是会被当成匿名函数来加载。还可以发现的是,使用默认输出之后,在`import`时不再需要大括号了,这是因为`export default`只能使用一次,所以在引入时可以不加大括号。**

正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。

// 正确
export var a = 1;

// 正确
var a = 1;
export default a;

// 错误
export default var a = 1;

// 正确
export default 42;

// 报错
export 42;

### 复合写法

如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。例如下面:

export { foo, bar } from 'my_module';

// 可以简单理解为
import { foo, bar } from 'my_module';
export { foo, bar };

上面代码中,export和import语句可以结合在一起,写成一行。但需要注意的是,写成一行以后,foo和bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用foo和bar。
88 changes: 88 additions & 0 deletions Generator函数.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: Generator函数
date: 2018-09-12 16:09:54
tags:
- JavaScript
- ECMAScript6
categories:
- ECMAScript6
---
# Generator函数
昨天的`Promise`对象就是一种异步编程解决方案,今天再看一种方案,这就是`Generator`函数。
网上有很多关于`Generator`的介绍,例如:
>Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

## Generator的创建
接下来我们看一下怎么定义一个Generator函数:

function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();

我们发现在`function`关键字和函数名称之间有个星号,这表示这是一个Generator函数。但这样还不行,进入函数我们发现使用了`yield`表达式,定义了不同的内部状态(`yield`在英语中就是“产生”的意思)。这样我们一共定义了三个状态:hello、word和一个return语句。

## Generator的调用
Generator函数返回的是一个遍历器对象,也就是说我们需要调用`next`方法来遍历函数中的状态:

hw.next()
// { value: 'hello', done: false }

hw.next()
/ { value: 'world', done: false }

hw.next()
// { value: 'ending', done: true }

hw.next()
/ { value: undefined, done: true }

上面一共运行了四次`next`方法。

第一次调用,Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束。

第二次调用,Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值world,done属性的值false,表示遍历还没有结束。

第三次调用,Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

第四次调用,此时 Generator 函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。

## Generator函数的作用
这个东西看上去好像没啥用,那么它到底能干点啥呢?

### 把异步回调变成‘同步’代码
例如我们写个ajax代码:

ajax('http://url-1', data1, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-2', data2, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-3', data3, function (err, result) {
if (err) {
return handle(err);
}
return success(result);
});
});
});

这个代码简直不想看,那么我们可以用Generator来改造下:

try {
r1 = yield ajax('http://url-1', data1);
r2 = yield ajax('http://url-2', data2);
r3 = yield ajax('http://url-3', data3);
success(r3);
}
catch (err) {
handle(err);
}

这样看上去好多了,但不是真正的同步代码,至少看上去很像。
33 changes: 33 additions & 0 deletions JS原型、原型链.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: JS原型理解
date: 2018-08-08 23:40:45
tags:
- JavaScript
categories:
- JavaScript
---

## JS原型和原型链

### js原型
js原型和原型链一直是js中一个难点,也是面试时大概率的问题,看了网上很多的说法,好像都不是那么通俗易懂。我就用简单的方式来介绍介绍,本人是前端菜鸟,说错了欢迎大家提出来。

>![](/img/js/1.png)
我理解中的原型是为了继承而产生的,为了防止污染全局变量,我们可以给Person的原型加上一个sayHello方法,这也是最简单的例子(自行脑补代码),这样我们就可以在Person的实例中共享sayHello这个方法。图中的每条线其实都可以用一个属性代替,我画出来你们就一目了然了。

>![](/img/js/2.png)
我们可以看到,Person构造函数可以通过prototype属性访问它自己的原型对象的,而实例化出来的对象可以通过\_proto\_属性访问Peroson构造函数的原型对象.\_proto\_属性其实是非标准的属性,也就是说这是浏览器为了方便才产生的属性,为了什么方便?当然是为了调试的方便啦,所以我们还是尽量不要在代码中使用\_proto\_,而在调试的时候使用。

### js原型链
上面给的是一个简单的原型模型,我们知道,原型对象还有一个属性constructor,这个属性就是指向该对象的构造函数的。下面我们需要了解几个概念,以便我们清楚的知道原型链是什么:<br>
**1.每个构造函数都有原型对象**<br>
**2.每个对象都会有构造函数**<br>
**3.每个构造函数的原型都是一个对象**<br>
**4.那么这个原型对象也会有构造函数**<br>
**5.那么这个原型对象的构造函数也会有原型对象**<br>
这样就形成一个链式结构,也就是我们说的原型链
>![](/img/js/3.png)
从图中我们就可以清楚的看到一个原型链结构,我们的原型其实也是个对象,对象也是由对象构造函数生成的,其实也就是之前的原型三角结构的延伸,可以看到,所有的对象的原型最顶层就是null。
13 changes: 13 additions & 0 deletions Jade怎么玩.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: Jade怎么玩
date: 2018-09-13 10:24:18
tags:
- Jade
categories:
- Jade
---
前端想要用模板,那就看看`Jade`吧,打开我们的[Jade官网](http://jade-lang.com/),上去看看呢,结果发现官网真的很水,水在哪呢?特喵的,给的代码没有一个注意缩进的,这也就导致后面很多模板使用jade命令时报错,有失水准啊!

好在咋们国人搞的还是比较靠谱:[点这可以学习Jade](http://www.nooong.com/docs/jade_chinese.htm)

**你不会真以为我要写个技术博客吧,我只是来吐槽下,Jade很简单,自己去学吧,几分钟就会了。**
83 changes: 83 additions & 0 deletions Koa中使用Cookie-Session.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
title: Koa中使用Cookie & Session
date: 2018-09-06 10:43:21
tags:
- Node
- Koa
categories:
- Node
---
# koa中cookie和session使用
---
### cookie介绍
cookie 是存储于访问者的计算机中的变量(客户端)。可以让我们用同一个浏览器访问同一个域名的时候共享数据。那为什么不使用http呢?很简单,因为HTTP 是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页面,服务器无法认识到这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何关系的。

### cookie用处
随便举几个例子:

1. 存储用户信息,例如登陆信息。
2. 浏览历史记录。
3. 猜你喜欢的功能。
4. 10天免登陆。
5. 多个页面之间的数据传递。
6. 实现购物车功能。

### Koa Cookie的使用

###### Koa中设置Cookie的值

ctx.cookies.set(name, value, [options])

通过options设置cookie name的value:

|options名称|options值|
|:----------:|---------|
|maxAge|一个数字表示从 Date.now() 得到的毫秒数。|
|expires|cookie 过期的 Date|
|path|cookie 路径, 默认是'/'。|
|secure|安全 cookie 默认 false,设置成 true 表示只有 https 可以访问。|
|httpOnly|是否只是服务器可访问 cookie, 默认是 true|
|overwrite|一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie(不管路径或域)是否在设置此 Cookie 时从Set-Cookie 标头中过滤掉。|

###### Koa中设置中文Cookie

console.log(new Buffer('hello, world!').toString('base64'));// 转换成 base64 字符串:aGVsbG8sIHdvcmxkIQ==

console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString());// 还原 base64 字符串:hello, world!

---
### Session介绍
session 是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。

### Session 的工作流程
当浏览器访问服务器并发送第一次请求时,服务器端会创建一个session 对象,生成一个类似于 key,value的键值对,然后将key(cookie)返回到浏览器(客户)端,浏览器下次再访问时,携带key(cookie),找到对应的Session(value)。 客户的信息都保存在Session中。

### koa-session 的使用

npm install koa-session --save

###### 引入 express-session

const session = require('koa-session');

###### 设置官方文档提供的中间件

app.keys = ['some secret hurr'];
const CONFIG = {
key: 'koa:sess', //cookie key (default is koa:sess)
maxAge: 86400000, // cookie 的过期时间 maxAge in ms (default is 1 days)
overwrite: true, //是否可以 overwrite (默认 default true)
httpOnly: true, //cookie 是否只有服务器端可以访问 httpOnly or not (default true)
signed: true, //签名默认 true
rolling: false, //在每次请求时强行设置 cookie,这将重置 cookie 过期时间(默认:false)
renew: false, //(boolean) renew session when session is nearly expired,
};

app.use(session(CONFIG, app));

###### Cookie 和 Session 区别

1. cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2. cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗考虑到安全应当使用 session。
3. session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用 COOKIE。
4. 单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
23 changes: 23 additions & 0 deletions MongoDB怎么导入数据.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: MongoDB怎么导入数据
date: 2018-10-08 22:44:24
tags:
- MongoDB
categories:
- MongoDB
---
使用`node`的过程中使用了`MongoDB`,在MongoDB中怎么直接将数据导入数据库呢?我们只需要一条命令就行了。

> mongorestore -h dbhost -d dbname path
其中`dbhost`代表你的host,一般在自己的电脑上的话是`127.0.0.1``dbname`代表要导入的数据库,可以是不存在的,默认会创建一个新的数据库,`path`就是你的数据库数据存放的位置。**路径中最好不要有中文,以防导入失败。这行命令不需要进入到数据库里面再执行,直接在cmd中运行就可以了。**

想要导出的话也很简单,只要执行下面的命令:

> mongodump -h dbhost -d dbname -o dbdirectory
`-o dbdirectory`是指导出到哪个目录。但是导出之前我们需要打开我们的数据路服务:

> mongod --dbpath yourpath
再执行上面的导出命令就OK啦。
Loading

0 comments on commit 188ec56

Please sign in to comment.