1.ES6怎么来的

  • ECMAScript 和 JavaScript
    ECMA 是标准,JS 是实现
    ECMAScript 简称 ECMA 或 ES
  • 历史版本
    1996, ES1.0 Netscape 将 JS 提交给 ECMA 组织,ES 正式出现
    1999, ES3.0 被广泛支持
    2011, ES5.1 成为 ISO 国际标准
    2015, ES6.0 正式发布

    2.ES6兼容性

  • ES6(ES2015) 支持的环境 IE10+, Chrome, FireFox, 移动端, NodeJS
  • 解决不兼容办法,编译、转换
    在线转换
    或者提前编译

入门教程
阮一峰es6标准入门
深入浅出es6系列文章
冴羽老师的博客

3.变量 let 和 常量 const

  • var 的问题
    可以重复声明,没有报错和警告
    无法限制修改
    变量提升,没有块级作用域, { }
  • let 和 const
    不能重复声明
    都是块级作用域, { } 块内声明的,块外无效
    let 是变量,可以修改,声明变量后可立马赋值或使用时赋值
    const 保证变量指向的那个内存地址所保存的数据不得改动,对于基本数据类型的常量,不可修改,对于引用类型可修改;const命令声明常量后必须立马赋值。
    let,const 都会形成暂时性死区(TDZ): 声明变量之前,该变量都是不可用声明变量之前,该变量不可用
  • 块级作用域举例
    原来用 var 的方式,结果弹出的都是 3
    或者将变量 封装到函数里,限制作用域,但比较麻烦
    用 let 最简单,直接 var 改 let,解决作用域问题

作用域

  • 全局作用域
  • 函数作用域: function() {}
  • 块作用域: {}

解构赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 数组解构
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
// 对象解构
({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20

({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

应用场景

  • 交换变量值:[x, y] = [y, x]
  • 返回函数多个值:const [x, y, z] = Func()
  • 定义函数参数:Func([1, 2])
  • 提取JSON数据:const { name, version } = packageJson
  • 定义函数参数默认值:function Func({ x = 1, y = 2 } = {}) {}
  • 遍历Map结构:for (let [k, v] of Map) {}
  • 输入模块指定属性和方法:const { readFile, writeFile } = require("fs")

可迭代对象(iterable)

1
2
for (in)
for (of 可迭代对象)

可迭代对象:Set Map Generator array string ….. 等等
有 Symbol.iterator 这个属性,值是一个方法,方法返回了每一次 for of 迭代时候的值。

实现itercable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var some = {};
some[Symbol.iterator] = function () {
return {
next: function () {
if (this._first < 3) {
this._first++;
// done for of 遍历 结束???
return { value: "bye" + this._first, done: false };
} else {
return { done: true };
}
},
_first: 0
};
};
for (let a of some) {
console.log(a);
}
console.log([...some]);
// 元编程:对编程语言再编程(自定义)

String

模板字符串
Includes()
repeat()

Number

Number.EPSILON:Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON
Number.MIN_SAFE_INTEGER:最小的安全数值
Number.isNaN()
Math.cosh()

Function

Arrow function:this arguments prototype
参数默认值:function foo(a= 1) {}

Object

  • object.assign() 合并(浅拷贝)

    1
    2
    3
    var aaaa = {a: 1}
    var bbbb = {b: 2}
    var ccccc = Object.assign({}, aaaa, bbbb)
  • object.is : react 内部涉及到对比两次值的时候都用 object.is

  • Object.getPrototypeOf(f):f 对象的原型对象

    1
    2
    3
    4
    function Foo() {};
    Foo.prototype.a = () => {}
    var f = new Foo();
    Foo.prototype === Object.getPrototypeOf(f)
  • Object.setPrototypeOf(f)

Array

Array.from()
find()
findIndex()

Symbol

独一无二的值

数据结构

Map/WeakMap
Set/WeakSet

Proxy

元编程概念
定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)
修改默认行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let a = { a: 1 }
// set get
// Object.defineProperty
let b = new Proxy(a, {
get: (...rest) => {
console.log('get')
return Reflect.get(...rest);
},
set: (...rest) => {
console.log('set');
return Reflect.set(...rest);
},
deleteProperty: (...rest) => {
console.log('deleteProperty')
return Reflect.deleteProperty(...rest);
},
getPrototypeOf: (...rest) => {
return Reflect.getPrototypeOf(...rest);
}
})
b.a = 123;
console.log(b);

proxyObject.defineProperty相比,Object.defineProperty无法监听数组变化,只能劫持已定义的对象属性,但proxy支持get,set,deleteProperty等多达13种操作,直接监听对象而非属性并且监听数组;但proxy无法做到全部兼容,仅靠polyfill也无法垫平。

proxy与object.defineProperty详见

Class

js的class是语法糖:本质上还是function
Extends:继承,组合寄生继承
super()
Staic

ES-module

es6模块与CommonJS模块,前者输出值的引用,输出动态接口绑定,在模块编译时执行;后者输出值的拷贝,在运行时加载。
静态分析在动态的AMD和CommonJS里是无法做到的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import 命令会被 JavaScript 引擎静态分析,优先于模块内的其他内容执行。           
export 命令会有变量声明提前的效果。
```
静态分析:=> treeshaking: 只引入使用的代码,减小打包后的代码体积。


### Promise

三种状态:Pending, resolve, reject
回调地狱-> 链式调用: promise.then().then()
手写一个 Promise(一步步来,先主后次)
```js
function newPromise(fn) {
let self = this
self.status = 'pending'
self.value = undefined
self.reason = undefined
self.onFulfilled = null
self.onRejected = null
let resolve = (newValue) => {
if (self.status == 'pending') {
self.status = 'fulfilled'
self.value = newValue
self.onFulfilled(self.value)
}
}
let reject = (newReason) => {
if (self.status == 'pending') {
self.status = 'rejected'
self.reason = newReason
self.onFulfilled(self.reason )
}
}
fn(resolve, reject)
}

newPromise.prototype.then = function(onFulfilled, onRejected) {
if (this.status == 'pending') {
this.onFulfilled = onFulfilled
this.onRejected = onRejected
} else if (this.status == 'fulfilled') {
onFulfilled(this.value)
} else {
onRejected(this.reason)
}
return this
}

实现一个 Promise.all(异步任务调用,模仿event loop 先把未处理的promise放在队列,依次拿出执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Promise.all1 = function (promises) {
let results = []; //待处理队列
return new Promise(function (resolve, reject) {
promises.forEach(promise => {
promise.then(res => {
results.push(res);
if (results.length === promises.length) {
resolve(results);
}
})
.catch(reject);
});
});
}
let p1 = Promise.resolve(1)
let p2 = Promise.resolve(2)
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 2000);
})
Promise.all1([p1, p2, p3])
.then(console.log);

Microtask

4.函数-箭头函数

  • 箭头函数,就是函数的简写
    如果只有一个参数,() 可以省
    如果只有一个return,{}可以省
    1
    2
    3
    4
    5
    6
    7
    // 普通函数
    function name() {

    }
    // 箭头函数,去掉 function, 加上 =>
    () => {
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let show1 = function () {
console.log('abc')
}

let show2 = () => {
console.log('abc')
}

show1() // 调用函数
show2()

let show4 = function (a) {
return a*2
}

let show5 = a => a * 2 //简洁,类似python lambda 函数

console.log(show4(10))
console.log(show5(10))

5.函数-参数

  • 参数扩展/展开 …args
    收集剩余的参数,必须当到最后一个参数位置
    展开数组,简写,效果和直接把数组的内容写在这儿一样
  • 默认参数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function show(a, b, ...args) {
    console.log(a)
    console.log(b)
    console.log(args)
    }
    console.log(show(1, 2, 3, 4, 5))

    let arr1 = [1, 2, 3]
    let arr2 = [4, 5, 6]
    let arr3 = [...arr1, ...arr2]
    console.log(arr3)

    function show2(a, b=5, c=8) {
    console.log(a, b, c)
    }
    show2(88, 12)

6.解构赋值

1
2
3
4
5
6
7
8
let [a, b, c] = [1, 2, 3]
console.log(a, b, c)

let {x, y, z} = {x: 1, y: 2, z: 3}
console.log(x, y, z)

let [json, arr, num, str] = [{ a: 1, b: 2 }, [1, 2, 3], 8, 'str']
console.log(json, arr, num, str)
  • 解构赋值
    左右两个边结构必须一样
    右边必须是个东西
    声明和赋值赋值不能分开,(必须在一句话里完成)

7.数组

新增4个方法

  • map 映射 一个对一个
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    let arr = [12, 5, 8]
    let result = arr.map(function (item) {
    return item*2
    })
    let result2 = arr.map(item=>item*2) // 简写
    console.log(result)
    console.log(result2)

    let score = [18, 86, 88, 24]
    let result3 = score.map(item => item >= 60 ? '及格' : '不及格')
    console.log(result3)

    // 结果
    [ 24, 10, 16 ]
    [ 24, 10, 16 ]
    [ '不及格', '及格', '及格', '不及格' ]
  • reduce 汇总 一堆出来一个
    用于比如,算个总数,算个平均
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var arr = [1, 3, 5, 7]
var result = arr.reduce(function (tmp, item, index) {
//tmp 上次结果,item当前数,index次数1开始
console.log(tmp, item, index)
return tmp + item
})
console.log(result)

var arr = [1, 3, 5, 7]
var result = arr.reduce(function (tmp, item, index) {
if (index != arr.length - 1) { // 不是最后一次
return tmp + item
} else {
return (tmp + item)/arr.length
}
})
console.log(result) // 平均值
  • filter 过滤器 保留为true的
1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [12, 4, 8, 9]
var result = arr.filter(item => (item % 3 === 0) ? true : false)
console.log(result)
var result = arr.filter(item => item % 3 === 0)
console.log(result)

var arr = [
{ title: '苹果', price: 10 },
{ title: '西瓜', price: 20 },
]
var result = arr.filter(json => json.price >= 20)
console.log(result)
```
  • forEach 循环迭代
1
2
3
var arr = [12, 4, 8, 9]
var result = arr.forEach(item => console.log(item))
var result = arr.forEach((item, index)=>console.log(item, index))

8.字符串

多了两个新方法

  • startWith 返回布尔值 表示参数字符串是否在源字符串的头部(用例eg:判断网址)
  • endsWith (根据后缀判断文件类型)
1
2
3
4
var url = 'http://qq.com'
console.log(url.startsWith('http'))
console.log(url.endsWith('com'))
// 都是 true
  • 字符串模板:使用反引号(`),${变量},可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

9.面向对象-基础

  • 原来写法
    类和构造函数一样
    属性和方法分开写的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 老版本
function User(name, pass) {
this.name = name
this.pass = pass
}

User.prototype.showName = function () {
console.log(this.name)
}
User.prototype.showPass = function () {
console.log(this.pass)
}

var u1 = new User('able', '1233')
u1.showName()
u1.showPass()
// 老版本继承
function VipUser(name, pass, level) {
User.call(this, name, pass)
this.level = level
}
VipUser.prototype = new User()
VipUser.prototype.constructor = VipUser
VipUser.prototype.showLevel = function () {
console.log(this.level)
}

var v1 = new VipUser('blue', '1234', 3)
v1.showName()
v1.showLevel()
  • 新版面向对象
    有了 class 关键字、构造器
    class 里面直接加方法
    继承,super 超类==父类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class User {
constructor(name, pass) {
this.name = name
this.pass = pass
}

showName() {
console.log(this.name)
}
showPass() {
console.log(this.pass)
}
}

var u1 = new User('able2', '111')
u1.showName()
u1.showPass()

// 新版本继承
class VipUser extends User {
constructor(name, pass, level) {
super(name, pass)
this.level = level
}
showLevel(){
console.log(this.level)
}
}

v1 = new VipUser('blue', '123', 3)
v1.showLevel()

10.面向对象应用

  • React
    用于构建用户界面的 JavaScript 库
    组件化,一个组件就是一个 class

11.json

  • JSON 格式
    JavaScript Object Notation 的缩写,是一种用于数据交换的文本格式
    JSON 是 JS对象 的严格子集
  • JSON 的标准写法
    {“key”:”value”}
    只能用双引号
    所有的key都必须用双引号包起来
    方法可省略function eg:show:function(){…} = show(){…}
  • JSON 对象
    JSON 对象是 JavaScript 的原生对象,用来处理 JSON 格式数据,有两个静态方法
    JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象。 JSON.stringify(obj) :接受一个 JavaScript** 对象并将其转换为一个 **JSON 字符串
1
2
3
4
5
6
7
8
9
10
11
12
var json = {a: 12, b: 5}
var str = 'hi,' + JSON.stringify(json)
var url = 'http://www.xx.com/' + encodeURIComponent(JSON.stringify(json))
console.log(str)
console.log(url)

var str = '{"a": 12, "b": 4, "c": "abc"}'
var json = JSON.parse(str)
console.log(json)
hi,{"a":12,"b":5}
http://www.xx.com/%7B%22a%22%3A12%2C%22b%22%3A5%7D
{ a: 12, b: 4, c: 'abc' }
  • 对象(object)
    是 JavaScript 语言的核心概念,也是最重要的数据类型
    对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合
    对象的所有键名都是字符串, 所以加不加引号都可以
    如果键名是数值,会被自动转为字符串
    对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型
    如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用
    in 运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值
    for…in循环用来遍历一个对象的全部属性
  • 对象 简写
    key-value 一样时可以简写
    里面函数可以简写, 去掉
1
2
3
4
5
6
7
8
9
var a = 12, b = 5
console.log({a:a, b:b})
console.log({a, b})
console.log({a, b, c:"c"})
console.log({ a, b, show(){ console.log('a') }})
{ a: 12, b: 5 }
{ a: 12, b: 5 }
{ a: 12, b: 5, c: 'c' }
{ a: 12, b: 5, show: [Function: show] }

12.Promise

  • 异步和同步
    异步:操作之间没啥关系,同时进行多个操作
    同步:同时只能做一件事
    异步有时会让代码变得更复杂(回调地狱),同步代码简单
  • Promise 对象
    用同步的方式来书写异步代码
    Promise 让异步操作写起来,像在写同步操作的流程,不必一层层地嵌套回调函数
    改善了可读性,对于多层嵌套的回调函数很方便
    充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口
  • Promise 也是一个构造函数
    接受一个回调函数f1作为参数,f1里面是异步操作的代码
    返回的p1就是一个 Promise 实例
    所有异步任务都返回一个 Promise 实例
    Promise 实例有一个then方法,用来指定下一步的回调函数
1
2
3
4
5
function f1(resolve, reject) {
// 异步代码...
}
var p1 = new Promise(f1);
p1.then(f2); // f1的异步操作执行完成,就会执行f2。
  • Promise 使得异步流程可以写成同步流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 传统写法
step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// ...
});
});
});
});

// Promise 的写法
(new Promise(step1))
.then(step2)
.then(step3)
.then(step4);
  • Promise.all(promiseArray)方法
    将多个Promise对象实例包装,生成并返回一个新的Promise实例
    promise数组中所有的promise实例都变为resolve的时候,该方法才会返回
    并将所有结果传递results数组中
    promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象
1
2
3
4
5
6
var p1 = Promise.resolve(1),
p2 = Promise.resolve(2),
p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
console.log(results); // [1, 2, 3]
});
  • Promise.race([p1, p2, p3])
    Promse.race就是赛跑的意思
    哪个结果获得的快,就返回那个结果
    不管结果本身是成功状态还是失败状态

    13.generator-认识生成器函数

  • generator 生成器函数
    普通函数,一路到底
    generator函数,中间可以停,到哪停呢,用 yield 配合,交出执行权
    yield 有 放弃、退让、退位的意思
    需要调用next()方法启动执行,需要遇到 yield 停, 踹一脚走一步
    generator函数前面加一个 * 两边可以有空格,或靠近函数或function
    背后实际生成多个小函数,实现走走停停
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function show() {
console.log('a')
console.log('b')
}
show() // 普通函数

function *show2() {
console.log('1')
yield
console.log('2')
}
let genObj = show2()
genObj.next() // 1
genObj.next() // 2
genObj.next() // 最后了,没有结果

14.generator-yield是啥

  • generator —— 中间能停 走走停停(eg:请求数据的场合)
    用来消除异步操作
    有个 * 号 (eg: function *show() next()执行下一个)
    yield : “暂时放弃执行”
    yield可以传参,返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //yield相当于一面墙,分割不同的工作   
    function *炒菜(菜市场买回的菜){
    洗菜-> 洗好的菜

    let 干净的菜 = yield 洗好的菜

    干净的菜->切->丝

    let 切好的菜 = yield 丝

    切好的菜 -> 炒 ->熟的菜

    return 熟的菜
    }
  • yield
    既可传参,又可以返回
    第一个next()传参无效,只用来启动
  • 如果函数前漏掉 * 就是普通函数
    如果有yield会报错, ReferenceError: yield is not defined
    yield 只能在Generator函数内部使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function * show() {
console.log('1')
var a = yield
console.log('2')
console.log(a)
}
// yield 传参
var gen = show()
gen.next() // 1
gen.next() // 2 和 undefined 因为没有传参,yield没有返回值
var gen = show()
gen.next(10) // 1 第一次执行到yield,但没有执行赋值
gen.next(20) // 2 和 20

function* show2() {
console.log('1')
yield 10
console.log('2')
}
// yield 返回
var gen = show2()
var res1 = gen.next()
console.log(res1) // { value: 10, done: false }
var res2 = gen.next()
console.log(res2)
// { value: undefined, done: true } 最后的value需要return返回

15.generator-实例

  • Promise 适合一次读一组
  • generator 适合逻辑性的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 带逻辑-generator
runner(function * () {
let userData = yield $.ajax({url: 'getUserData'})

if (userData.type == 'VIP') {
let items = yield $.ajax({url: 'getVIPItems'})
} else {
let items = yield $.ajax({url: 'getItems'})
}
})
// yield 实例,用同步方式写异步
server.use(function * () {
let data = yield db.query(`select * from user_table`)
this.body = data
})

16.ES7 预览

  • 数组
    arr.includes() 数组是否包含某个东西
    数组的 arr.keys(), arr,entries()
    for … in 遍历数组 下标 key
    for … of 遍历数组 值 value, 不能用于json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let arr = ['a', 'b', 'c']
console.log(arr.includes(1))

for (let i in arr) {
console.log(i) // 循环的时下标 key
}

for (let i of arr) {
console.log(i) // 循环的是值 value
}
for (let i of arr.keys()) {
console.log('>'+i)
}
for (let [key, value] of arr.entries()) {
console.log('>' + key + value)
}

let json = { a: 12, b: 5, c: 7 }
for (let i in json) {
console.log(i)
}
  • 字符串
    padStart()/padEnd() 指定宽度,不够就补空格或指定字符
1
2
3
4
console.log('=' + 'abcd'.padStart(6, '0') + '=')
console.log('=' + 'abcd'.padEnd(6, '0') + '=')
=00abcd=
=abcd00=
  • 容忍度
    [1, 2, 3,] 老版数组最后不能有逗号,新的可以有
    函数参数最后多的逗号也可以
  • async await
    和 generator yield 类似
    generator 不可以写成箭头函数, async 可以
1
2
3
4
5
async function show() {
console.log(1)
await
console.log(2)
}
相关文章
评论
分享
  • 深拷贝与浅拷贝

    数据类型数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型 原始数据类型:保存在栈(stack)中,引用类型类型:存储的是该对象在栈中引用,真实...

    深拷贝与浅拷贝
  • 我的三月碎碎念

    前言现在三月中旬了,是待在家为祖国做贡献的第二个月,不在学校的日子,每天在家学习,也过的蛮充实。少了很多社交,昨天还和谷歌娘唠嗑些有的没的。每天的小结越写越短,那就这一次给自己写个阶段性的总结吧。 基础 这段时间赶上春招,社...

    我的三月碎碎念
  • 关于二叉树、递归、DFS、BFS

    前言前言:这是作为一个正在学习的前端开发者整理一下最近写的题,这文章是我对二叉树算法的浅显的理解,希望可以让你在看完文章之后对常见的二叉树操作有一定的了解,文中列举了我觉得比较经典的一些题目。有不对的地方欢迎指出。😮😮😮 本文...

    关于二叉树、递归、DFS、BFS
  • 李佳琦可视化list

    前言做这个李佳琦推荐口红可视化倒也不是因为自己喜欢买口红或者喜欢看李佳琦,是一次在车上逛微博看到热搜上一个帖子,很详细的整理了这些口红,用手机自带的备忘录写的,但略显简陋,颜色展示仅仅是在色号后面加了个很小的色卡,当时就想,如果可以做...

    李佳琦可视化list
  • 给阿姨倒一杯卡布奇诺

    前言图床老挂, 在掘金看吧,阅读体验更好 👉看这里 平安夜那天晚上下课打着伞想到的idea做出来了,写个总结 页面结构12345678"pages": [ "pages/buy/buy", ...

    给阿姨倒一杯卡布奇诺
  • 傲慢与偏见 Mr.Darcy

    淋雨的自杀式告白– Miss Elizabeth , I have struggled in vain and can bear it no longer. These past months have been a tor...

    傲慢与偏见 Mr.Darcy
  • 随笔杂谈

    关于《胜利之光》如果你正在经历挫折与失败,心灰意冷时,一定要看看这部电影 以后你可能再也找不到能让你这么热血拼搏的事情了趁现在你还有热血,趁现在你还有激情去做那些只要想到就会让你两眼放光的事情吧因为过了这段时间,你可能再也难以找到那种...

    随笔杂谈
  • Hello World

    Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using ...

    Hello World
Please check the comment setting in config.yml of hexo-theme-Annie!