-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 188ec56
Showing
50 changed files
with
4,026 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
|
||
这样看上去好多了,但不是真正的同步代码,至少看上去很像。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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中一个难点,也是面试时大概率的问题,看了网上很多的说法,好像都不是那么通俗易懂。我就用简单的方式来介绍介绍,本人是前端菜鸟,说错了欢迎大家提出来。 | ||
|
||
> | ||
我理解中的原型是为了继承而产生的,为了防止污染全局变量,我们可以给Person的原型加上一个sayHello方法,这也是最简单的例子(自行脑补代码),这样我们就可以在Person的实例中共享sayHello这个方法。图中的每条线其实都可以用一个属性代替,我画出来你们就一目了然了。 | ||
|
||
> | ||
我们可以看到,Person构造函数可以通过prototype属性访问它自己的原型对象的,而实例化出来的对象可以通过\_proto\_属性访问Peroson构造函数的原型对象.\_proto\_属性其实是非标准的属性,也就是说这是浏览器为了方便才产生的属性,为了什么方便?当然是为了调试的方便啦,所以我们还是尽量不要在代码中使用\_proto\_,而在调试的时候使用。 | ||
|
||
### js原型链 | ||
上面给的是一个简单的原型模型,我们知道,原型对象还有一个属性constructor,这个属性就是指向该对象的构造函数的。下面我们需要了解几个概念,以便我们清楚的知道原型链是什么:<br> | ||
**1.每个构造函数都有原型对象**<br> | ||
**2.每个对象都会有构造函数**<br> | ||
**3.每个构造函数的原型都是一个对象**<br> | ||
**4.那么这个原型对象也会有构造函数**<br> | ||
**5.那么这个原型对象的构造函数也会有原型对象**<br> | ||
这样就形成一个链式结构,也就是我们说的原型链 | ||
> | ||
从图中我们就可以清楚的看到一个原型链结构,我们的原型其实也是个对象,对象也是由对象构造函数生成的,其实也就是之前的原型三角结构的延伸,可以看到,所有的对象的原型最顶层就是null。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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很简单,自己去学吧,几分钟就会了。** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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啦。 |
Oops, something went wrong.