Cherry的博客


  • 主页

  • 文章

微信小程序调用云函数

Posted on 2019-02-21

云开发过程调用云函数出错问题

新建云开发QuickStart项目

报错信息
1
upload score failed Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail cloud function service error code -504002, error message Cannot find module 'wx-server-sdk'; at cloud.callFunction api;

错误原因是服务端node.js没有安装所依赖的’wx-server-sdk’模块。此时需要右键打开控制终端,运行命令

1
npm install --save wx-server-sdk@latest

此时根据官网右键上传并部署所有文件,编译,再次点击,发现还是会出现错误。

1
get openid failed with error Error: errCode: -404011 cloud function execution error | errMsg: cloud.callFunction:fail cloud function service error code -504002, error message Function not found: [login]; at cloud.callFunction api;

在这一步,真的是卡住了,运行环境也有,依赖也有,还是报错,心累,最后发现初始化时需要直接填写默认环境,wx.cloud.init({env:’test-08f027’});

注意,此时的默认环境需要写的是环境id

最终,大功告成,小程序的第一步终于结束。

ES6

Posted on 2018-10-07

个人回顾整理学习。

关于变量

ES5

全部作用域变量和函数作用域变量

“变量提升” 程序进入某一个函数时,会先将函数内的变量声明放在函数开头,不会提升变量的赋值。

1
2
console.log(foo); // 输出:undefined
var foo = 2;

ES6

变量声明let和const

块级作用域

没有“变量提升”,必须先声明后使用

let 声明的变量不能重复

const 定义的是只读变量,需在声明时即赋值,变量名不能重复

1
2
console.log(bar); // 报错
let bar = 2;

块级作用域的应用场景

内层变量可能会覆盖外层变量

1
2
3
4
5
6
7
8
9
10
> var tmp = new Date();
> function f() {
> console.log(tmp);
> if (false) {
> var tmp = 'hello world';
> }
> }
>
> f(); // undefined
>

用来计数的循环变量泄露为全局变量

1
2
3
4
5
6
7
8
> var s = 'hello';
>
> for (var i = 0; i < s.length; i++) {
> console.log(s[i]);
> }
>
> console.log(i); // 5
>

不必要立即执行函数表达式

1
2
3
4
5
6
7
8
9
10
11
12
> // IIFE 写法
> (function () {
> var tmp = ...;
> ...
> }());
>
> // 块级作用域写法
> {
> let tmp = ...;
> ...
> }
>

应尽量避免在块级作用域中声明函数

声明变量的方式

var function let const import class

变量的结构赋值

数组

ES5

1
2
3
$ let a = 1;
$ let b = 2;
$ let c = 3;

ES6

1
$ let [a, b, c] = [1, 2, 3];

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ 嵌套数组结构
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

不完全结构

1
2
3
4
5
6
7
8
let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
对象
1
2
3
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

等价于

1
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
字符串
1
2
3
4
5
6
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

length 属性

1
2
let {length : len} = 'hello';
len // 5

关于数组

扩展运算符

… 数组的展开运算

1
2
3
var arr = [1,2,3,4,5];
console.log(arr);//[1, 2, 3, 4, 5]
console.log(...arr)// 1 2 3 4 5

函数批量传参

1
fun5(...[11,22,33,44,55,66])

替代函数apply方法

应用Math.max方法,简化求出一个数组最大元素的写法。

1
2
3
4
5
6
7
8
// ES5 的写法
Math.max.apply(null, [14, 3, 77])

// ES6 的写法
Math.max(...[14, 3, 77])

// 等同于
Math.max(14, 3, 77);

push函数

1
2
3
4
5
6
7
8
9
// ES5的 写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);

// ES6 的写法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);

应用

复制数组

数组是复合数据类型,直接复制的话只是复制了指向底层数据结构的指针,而不是克隆一个新的数组。

1
2
3
4
5
const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]
1
ES5 变通方法克隆数组
1
2
3
4
5
const a1 = [1, 2];
const a2 = a1.concat();

a2[0] = 2;
a1 // [1, 2]
1
ES6 扩展运算符简单写法
1
2
3
4
5
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
合并数组
1
2
3
4
5
6
7
8
9
10
11
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

注意

这两种方法合成的新数组都是对原数组成员的引用,属于浅拷贝,如果原数组成员改变,则会反映到新合成的数组上。

与结构赋值结合
1
2
3
4
5
6
7
8
9
10
11
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]

const [first, ...rest] = [];
first // undefined
rest // []

const [first, ...rest] = ["foo"];
first // "foo"
rest // []

注意

采用此方法,数组扩展运算符只能放在参数的最后一位,否则,报错。

字符串

扩展运算符可以将字符串转为数组

1
2
[...'hello']
// [ "h", "e", "l", "l", "o" ]
Array.form()

Array.from用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象。

1
2
3
4
5
6
7
8
9
10
11
12
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};

// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

实际应用中,常见的类似数组的对象是 DOM 操作返回的 NodeList 集合,以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。

1
2
3
4
5
6
7
8
9
10
11
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).filter(p => {
return p.textContent.length > 100;
});

// arguments对象
function foo() {
var args = Array.from(arguments);
// ...
}

字符串扩展

字符串 for…of 遍历

1
2
3
4
5
6
for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"

ES5

indexOf 用来确定一个字符串是否包含在另一个字符串中

ES6

Includes() 返回布尔值 是否找到参数字符串

startsWith() 返回布尔值 表示参数是否在原字符串头部

endsWith() 返回布尔值 表示参数是否在原字符串尾部

备注

这三个方法都支持第二个参数,表示开始搜索的位置。

使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束

repeat()

返回一个新字符串,表示将原字符串重复n次

1
2
3
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""

参数如果是小数,会被取整

1
'na'.repeat(2.9) // "nana"

备注

  • 如果repeat的参数是负数或者Infinity,会报错
  • 如果参数是 0 到-1 之间的小数,则等同于 0
  • 参数NaN等同于 0
padStart(), padEnd()

字符串补全长度的功能,如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

1
2
3
4
5
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
模板字符串

ES5

1
2
3
4
5
6
$('#result').append(
'There are <b>' + basket.count + '</b> ' +
'items in your basket, ' +
'<em>' + basket.onSale +
'</em> are on sale!'
);

ES6

模板字符串是增强版的字符串,反引号(`)标识。可以当做普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

1
2
3
4
5
$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);

模板字符串中嵌入变量,需要将变量名写在${}之中。

1
2
3
4
5
6
7
8
9
10
11
12
function authorize(user, action) {
if (!user.hasPrivilege(action)) {
throw new Error(
// 传统写法为
// 'User '
// + user.name
// + ' is not authorized to do '
// + action
// + '.'
`User ${user.name} is not authorized to do ${action}.`);
}
}

大括号内部可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性

1
2
3
4
5
6
7
8
9
10
11
12
let x = 1;
let y = 2;

`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"

`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"

let obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"

对象扩展

属性简洁表示

ES6 允许直接写入变量和函数。

1
2
3
4
5
6
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}

// 等同于
const baz = {foo: foo};

方法简写

1
2
3
4
5
6
7
8
9
10
11
12
13
const o = {
method() {
return "Hello!";
}
};

// 等同于

const o = {
method: function() {
return "Hello!";
}
};

属性名表达式

除了用标识符作为属性名,ES6 增加了使用表达式作为对象的属性名,需要放在[]中。

1
2
3
4
5
// 方法一
obj.foo = true;

// 方法二
obj['a' + 'bc'] = 123;
1
2
3
4
5
6
7
8
9
10
let lastWord = 'last word';

const a = {
'first word': 'hello',
[lastWord]: 'world'
};

a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"

Object.is()

ES5 比较两个值是否相等:==(相等运算符)和 ===(严格相等运算符)。

ES6 Object.is() 与=== 行为基本一致。

1
2
3
4
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false

两个不同之处

1
2
3
4
5
+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

Object.assign()

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

1
2
3
4
5
6
7
const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

注意

  • 浅拷贝(如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用)
  • 同名属性替换不是添加
  • 处理数组是会把数组视为对象
  • 如果复制的是一个函数,则函数取值后再进行复制

Object.assign() 应用

为对象添加属性

将x属性和y属性添加到Point类的对象实例。

1
2
3
4
5
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
为对象添加方法

使用assign方法添加到SomeClass.prototype之中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
克隆对象
1
2
3
function clone(origin) {
return Object.assign({}, origin);
}
合并多个对象
1
2
const merge =
(target, ...sources) => Object.assign(target, ...sources);

属性的遍历

(1) for…in

循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)

(2)Object.keys(obj)

返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

(3)Object.getOwnPropertyNames(obj)

返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

(4)Object.getOwnPropertySymbols(obj)

返回一个数组,包含对象自身的所有 Symbol 属性的键名。

(5)Reflect.ownKeys(obj)

返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

扩展运算符

对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

1
2
3
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
1
2
3
let aClone = { ...a };
// 等同于
let aClone = Object.assign({}, a);

合并对象

1
2
3
let ab = { ...a, ...b };
// 等同于
let ab = Object.assign({}, a, b);

Symbol

ES6 引入一种新的原始数据类型Symbol,表示独一无二的值。

对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

1
2
3
4
let s = Symbol();

typeof s
// "symbol"

Set和Map数据结构

Set

含义和用法

Set 数据结构类似数组,但是它的值都是唯一的,没有重复的值。

1
2
3
4
5
6
7
8
const s = new Set();

[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
console.log(i);
}
// 2 3 5 4

Set 可以接受一个数组参数,用来初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 例一
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

// 例二
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5

// 例三
const set = new Set(document.querySelectorAll('div'));
set.size // 56

// 类似于
const set = new Set();
document
.querySelectorAll('div')
.forEach(div => set.add(div));
set.size // 56

去除数组重复成员

1
2
// 去除数组的重复成员
[...new Set(array)]
Set 实例属性和方法

属性

  • Set.prototype.constructor:构造函数,默认就是Set函数。
  • Set.prototype.size:返回Set实例的成员总数。

操作方法

  • add(value):添加某个值,返回 Set 结构本身。
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示该值是否为Set的成员。
  • clear():清除所有成员,没有返回值。

判断是否包括一个键,Object结构和Set结构的写法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 对象的写法
const properties = {
'width': 1,
'height': 1
};

if (properties[someName]) {
// do something
}

// Set的写法
const properties = new Set();

properties.add('width');
properties.add('height');

if (properties.has(someName)) {
// do something
}

Array.from方法可以将 Set 结构转为数组。

1
2
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

数组去重

1
2
3
4
5
function dedupe(array) {
return Array.from(new Set(array));
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

遍历方法

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

Map

含义及用法

ES6 提供Map结构,类似于对象,对象本质上是键值对的集合,Object 结构只能字符串当做对象的键,而Map结构“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应。

1
2
3
4
5
6
7
8
9
const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false
实例属性及操作方法

(1)size 属性

(2)set(key, value)

set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。set方法返回的是当前的Map对象,因此可以采用链式写法。

1
2
3
4
let map = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');

(3)get(key)

get方法读取key对应的键值,如果找不到key,返回undefined。

(4)has(key)

has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。

(5)delete(key)

delete方法删除某个键,返回true。如果删除失败,返回false。

(6)clear()

clear方法清除所有成员,没有返回值。

数值扩展

二进制和八进制表示法

分别用前缀0b(或0B)和0o(或0O)表示二进制和八进制

Number.isFinite(), Number.isNaN()

Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity。

Number.isNaN()用来检查一个值是否为NaN。

这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。

Number.parseInt(), Number.parseFloat()

和全局方法相比行为完全不变,是为了减少全局方法的使用,使语言逐步模块化。

Number.isInteger()

用来判断一个数值是否为整数,如果不是数值返回false

1
2
3
4
Number.isInteger(25) // true
Number.isInteger(25.1) // false
Number.isInteger(25) // true
Number.isInteger(25.0) // true

Math 对象扩展

Math.trunc()

Math.trunc方法用于去除一个数的小数部分,返回整数部分。

注意

  • 对于非数值,Math.trunc内部使用Number方法将其先转为数值
  • 对于空值和无法截取整数的值,返回NaN
Math.sign()

Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

  • 参数为正数,返回+1
  • 参数为负数,返回-1
  • 参数为 0,返回0
  • 参数为-0,返回-0
  • 其他值,返回NaN

关于函数

函数默认值

ES6

给形参函数设置默认值,构造函数同理

1
2
3
4
5
function fun2(a=1,b=2){
console.log(a,b)//1,2
}
fun2(11,22);//11 22
fun2(100);//100 2

箭头函数

1
2
3
4
5
6
7
//正常函数
var fun3 = function(a){
console.log(a);
}
//箭头函数
var fun3 = (a)=>{console.log(a);}
fun3(999);
this知识

函数体外this指window对象

函数体内,谁调用函数this就指向谁

构造函数,this指的是新创建的对象

html标签中,this指的是这个标签元素

ES6 对于箭头函数,this指向需要根据在哪里创建和当前作用域确定。

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  • 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
不适用场合
  • 定义函数的方法,且该方法内部包括this
1
2
3
4
5
6
const cat = {
lives: 9,
jumps: () => {
this.lives--;
}
}

上面代码中,cat.jumps()方法是一个箭头函数,这是错误的。调用cat.jumps()时,如果是普通函数,该方法内部的this指向cat;如果写成上面那样的箭头函数,使得this指向全局对象,因此不会得到预期结果。

  • 需要动态this的时候,也不应使用箭头函数
1
2
3
4
var button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on');
});

上面代码运行时,点击按钮会报错,因为button的监听函数是一个箭头函数,导致里面的this就是全局对象。如果改成普通函数,this就会动态指向被点击的按钮对象。

双冒号运算符

函数绑定运算符(::),用来取代call、apply、bind调用。冒号左边是对象,右边是一个函数。双冒号运算符会自动将左边对象作为上下文环境(this对象)绑定到右边函数。

1
2
3
4
5
6
7
8
9
10
11
12
foo::bar;
// 等同于
bar.bind(foo);

foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);

const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return obj::hasOwnProperty(key);
}

如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。

1
2
3
4
5
6
7
var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;

let log = ::console.log;
// 等同于
var log = console.log.bind(console);

如果双冒号运算符的运算结果,还是一个对象,就可以采用链式写法。

尾部调用

尾调用(Tail Call)是函数式编程的一个重要概念,本身非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。

1
2
3
function f(x){
return g(x);
}

尾递归

函数调用自身,称为递归。如果尾调用自身,就称为尾递归。

1
递归
1
2
3
4
5
6
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}

factorial(5) // 120

上面代码是一个阶乘函数,计算n的阶乘,最多需要保存n个调用记录,复杂度 O(n)

1
尾递归
1
2
3
4
5
6
function factorial(n, total) {
if (n === 1) return total;
return factorial(n - 1, n * total);
}

factorial(5, 1) // 120

如果改写成尾递归,只保留一个调用记录,复杂度 O(1) 。

Proxy

🏠简介

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

1
var proxy = new Proxy(target, handler);

其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

拦截读取属性

1
2
3
4
5
6
7
8
9
var proxy = new Proxy({}, {
get: function(target, property) {
return 35;
}
});

proxy.time // 35
proxy.name // 35
proxy.title // 35

注意,要使得Proxy起作用,必须针对Proxy实例(上例是proxy对象)进行操作,而不是针对目标对象(上例是空对象)进行操作。

如果handler没有设置任何拦截,那就等同于直接通向原对象。

1
2
3
4
5
var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"

Reflect

🏠简介

ES6 为了操作对象提供的新的API。

(1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。

(2) 修改某些Object方法的返回结果,让其变得更合理。

(3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

(4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。

静态方法

Reflect.get(target, name, receiver)

Reflect.get方法查找并返回target对象的name属性,如果没有该属性,则返回undefined。

如果name属性部署了读取函数(getter),则读取函数的this绑定receiver。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
},
};

var myReceiverObject = {
foo: 4,
bar: 4,
};

Reflect.get(myObject, 'baz', myReceiverObject) // 8
Reflect.set(target, name, value, receiver)

Reflect.set方法设置target对象的name属性等于value。

如果name属性设置了赋值函数,则赋值函数的this绑定receiver。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var myObject = {
foo: 4,
set bar(value) {
return this.foo = value;
},
};

var myReceiverObject = {
foo: 0,
};

Reflect.set(myObject, 'bar', 1, myReceiverObject);
myObject.foo // 4
myReceiverObject.foo // 1
Reflect.has(obj, name)

Reflect.has方法对应name in obj里面的in运算符。

1
2
3
4
5
6
7
8
9
var myObject = {
foo: 1,
};

// 旧写法
'foo' in myObject // true

// 新写法
Reflect.has(myObject, 'foo') // true
Reflect.deleteProperty(obj, name)

Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。

1
2
3
4
5
6
7
const myObj = { foo: 'bar' };

// 旧写法
delete myObj.foo;

// 新写法
Reflect.deleteProperty(myObj, 'foo');
Reflect.construct(targer, args)

Reflect.construct方法等同于new target(...args),这提供了一种不使用new,来调用构造函数的方法。

1
2
3
4
5
6
7
8
9
function Greeting(name) {
this.name = name;
}

// new 的写法
const instance = new Greeting('张三');

// Reflect.construct 的写法
const instance = Reflect.construct(Greeting, ['张三']);

应用

使用Proxy实现观察者模式。

观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
const person = observable({
name: '张三',
age: 20
});

function print() {
console.log(`${person.name}, ${person.age}`)
}

observe(print);
person.name = '李四';
// 输出
// 李四, 20

Promise 对象

🏠简介

Promise 是异步编程的一种解决方案。

  • Promise 对象的状态不受外界影响。
  • 代表异步操作,有三种状态:pending(进行中),fulfilled(已成功),rejected(已失败)。
  • 一旦状态改变,就不会再变,任何时候都是这个结果。有两种可能的状态改变:由pending变为fulfilled,由pending变为rejected。

优势:

  • 表达方面,将异步操作用同步操作的形式表达出来,避免了层层嵌套。
  • 提供统一的接口,使异步操作更加方便。

缺点:

  • Promise无法取消,一旦创建,立即执行。
  • 如果不设置回调函数,Promise内部报错,不会反映到外部。
  • 处于pending状态时无法知道进展到哪个阶段,是刚刚开始还是马上结束。

基本用法

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。

1
2
3
4
5
6
7
8
9
const promise = new Promise(function(resolve, reject) {
// ... some code

if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

1
2
3
4
5
promise.then(function(value) {
// success
}, function(error) {
// failure
});

链式调用

1
2
3
4
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。

Promise.all()

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

1
const p = Promise.all([p1, p2, p3]);

其中p的状态由p1 p2决定

  • 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
  • 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
1
2
3
4
5
6
7
8
9
10
// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json");
});

Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});

Promise.resolve()

Promise.resolve可以将现有对象转为 Promise 对象。

1
2
3
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
  • 参数是Promise实例,返回这个实例
  • 参数是一个thenable对象(具有then方法的对象),Promise.resolve将其转化为Promise对象,并立即执行thenable对象的then方法
  • 参数不是具有then方法的对象,或根本就不是对象,返回一个新的Promise对象,状态为resolved
  • 不带参数,直接返回一个resolved状态的 Promise 对象

Promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

1
2
3
4
5
6
7
8
const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

p.then(null, function (s) {
console.log(s)
});
// 出错了

应用

加载图片
1
2
3
4
5
6
7
8
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};
Generator函数与Promise结合

Iterator、for…of 循环

表示”集合“的数据结构:Array,Object,Map,Set。需要一个统一的接口机制,开处理不同的数据结构。

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。

Iterator 作用

  • 为各种数据结构提供统一的、简便的访问接口
  • 使得数据结构的成员能够按照某种次序排列
  • 创造一种新的遍历命令,for…of循环

模拟next方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{value: undefined, done: true};
}
};
}

默认 Iterator 接口

一种数据结构只要部署了Iterator接口,就称这种数据结构是”可遍历的“。ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。

原生具备Iterator接口的数据:

  • Array
  • Map
  • Set
  • String
  • TypeArray
  • 函数的 arguments 对象
  • NodeList 对象

调用Iterator接口的情况

结构赋值

对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法。

1
2
3
4
5
6
7
let set = new Set().add('a').add('b').add('c');

let [x,y] = set;
// x='a'; y='b'

let [first, ...rest] = set;
// first='a'; rest=['b','c'];
扩展运算符
1
2
3
4
5
6
7
8
/ 例一
var str = 'hello';
[...str] // ['h','e','l','l','o']

// 例二
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']
yield*
其他情况

由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。

  • for…of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]]))
  • Promise.all()
  • Promise.race()

Iterator接口

Symbol.Iterator方法的简单实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let myIterable = {
[Symbol.iterator]: function* () {
yield 1;
yield 2;
yield 3;
}
}
[...myIterable] // [1, 2, 3]

// 或者采用下面的简洁写法

let obj = {
* [Symbol.iterator]() {
yield 'hello';
yield 'world';
}
};

for (let x of obj) {
console.log(x);
}
// "hello"
// "world"

for…of

JavaScript 原有的for...in循环,只能获得对象的键名,不能直接获取键值。ES6 提供for...of循环,允许遍历获得键值。

1
2
3
4
5
6
7
8
9
var arr = ['a', 'b', 'c', 'd'];

for (let a in arr) {
console.log(a); // 0 1 2 3
}

for (let a of arr) {
console.log(a); // a b c d
}

优点:

  • 有着同for...in一样的简洁语法,但是没有for...in那些缺点。
  • 不同于forEach方法,它可以与break、continue和return配合使用。
  • 提供了遍历所有数据结构的统一操作接口。

async 函数

Generator函数的语法糖

async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。

async函数的返回值是一个Promise对象。

async可以看做是多个一步操作包装成的一个Promise对象,await命令就是内部then命令的语法糖。

基本用法

async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,遇到await函数就会先返回,等到异步操作完成,才会执行函数体后面的语句。

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
// 函数声明
async function foo() {}

// 函数表达式
const foo = async function () {};

// 对象的方法
let obj = { async foo() {} };
obj.foo().then(...)

// Class 的方法
class Storage {
constructor() {
this.cachePromise = caches.open('avatars');
}

async getAvatar(name) {
const cache = await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`);
}
}

const storage = new Storage();
storage.getAvatar('jake').then(…);

// 箭头函数
const foo = async () => {};

返回Promise对象

async函数内部return返回的值,会成为then回调函数的参数。

1
2
3
4
5
6
async function f() {
return 'hello world';
}

f().then(v => console.log(v))
// "hello world"

async函数发生错误,会使返回的Promise对象变为reject状态,错误信息可以由catch方法得到。

1
2
3
4
5
6
7
8
9
async function f() {
throw new Error('出错了');
}

f().then(
v => console.log(v),
e => console.log(e)
)
// Error: 出错了

Promise对象的状态变化

async函数返回的Promise对象,只有函数内部await函数后边跟着的Promise对象执行完毕,才会产生状态改变,除非遇到return函数,或者发生错误。

async函数内部的异步操作执行完成,才会执行then回调函数操作。

1
2
3
4
5
6
7
async function getTitle(url) {
let response = await fetch(url);
let html = await response.text();
return html.match(/<title>([\s\S]+)<\/title>/i)[1];
}
getTitle('https://tc39.github.io/ecma262/').then(console.log)
// "ECMAScript 2017 Language Specification"

await 命令

通常await函数后面是一个Promise对象,如果不是,则返回相应的值。

1
2
3
4
5
6
7
8
async function f() {
// 等同于
// return 123;
return await 123;
}

f().then(v => console.log(v))
// 123

只要一个await函数后面的Promise对象变为reject,则async函数就会中断执行,如果一个await函数出错,使其不影响后续await函数的执行,就需要将其加上try…catch结构。

1
2
3
4
5
6
7
8
9
10
11
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// hello world

另一种方法是在await函数后面的Promise对象加上一个catch方法。

1
2
3
4
5
6
7
8
9
10
async function f() {
await Promise.reject('出错了')
.catch(e => console.log(e));
return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// 出错了
// hello world

注意点

  • 最好把await函数放在try..catch结构中
  • 多个await函数如果不存在继发关系,最好让他们同时触发
1
2
3
继发触发
let foo = await getFoo();
let bar = await getBar();
1
2
3
4
5
6
7
8
9
同时触发
// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
  • await函数只能写在async函数中

apply 和 call

对象本身没有某个属性或者方法,进而使用apply或者call去引用其他对象的属性方法,改变this的指向。

使用方法

apply(this指向,数组/arguments)

call(this指向,参数1,参数2,参数3)

1
2
3
4
5
6
7
8
9
10
11
var name ="window的name";
var obj = {
name:"obj的name",
showName:function(v1,v2,v3){
console.log(v1,v2,v3)
}
}
obj.showName();
obj.showName.apply(window,[10,20,30]);//10 20 30
//apply括号里的是谁,调用的前面的函数里面的this就是谁
obj.showName.call(window,10,20,30)//10 20 30

参考链接

ES5

Posted on 2018-09-29

ES5

个人的回顾整理学习。

语法

基本语法包括数据类型,操作符,语句,函数

数据类型:Number,String,Boolean,Null,Undefined,Array,Object

操作符:算数操作符,布尔操作符,赋值操作符

语句:if语句,for语句,case语句等

类型

Undefined 类型

有且只有一个值称为undefined。任何没有被赋值的变量都有undefined值。

Null

有且只有一个值null

Boolean 类型

表示逻辑实体 true或false

String 类型

字符串类型是所有有限的零个或多个 16 位无符号整数值(“元素”)的有序序列

Number 类型

数值类型拥有 18437736874454810627(即,264-253 +3)个值,非数字值 NaN

特殊值:正无穷和负无穷 +Infinity -Infinity

Object 类型

属性的集合。

引用规范类型

用来说明 delete,typeof,赋值运算符这些运算符的行为

类型转换

ToPrimitive

接受一个值和一个可选类型作为参数,可以把值转换为非对象类型

输入类型 结果
Undefined 结果等于输入的参数(不转换)
Null 结果等于输入的参数(不转换
Boolean 结果等于输入的参数(不转换
Number 结果等于输入的参数(不转换
String 结果等于输入的参数(不转换
Object 返回该对象的默认值。(调用该对象的内部方法[[DefaultValue]]一样)

ToBoolean

将其参数转换为布尔值类型的值

输入类型 结果
Undefined false
Null false
Boolean 结果等于输入的参数(不转换)
Number 如果参数是 +0, -0, 或 NaN, 结果为 false , 否则结果为 true
String 如果参数参数是空字符串(其长度为零),结果为 false,否则结果为 true
Object true

ToNumber

将参数转换为数值类型的值

输入类型 结果
Undefined NaN
Null +0
Boolean 如果参数是 true,结果为 1; 如果参数是 false,此结果为 +0
Number 结果等于输入的参数(不转换)
String
Object 设 原始值 为 ToPrimitive( 输入参数 , 暗示 数值类型)。 返回 ToNumber( 原始值 )

ToInteger

将参数转化为整数值

  1. 对输入参数调用 ToNumber
  2. 如果 Result(1) 是 NaN,返回 +0
  3. 如果 Result(1) 是 +0 ,-0,+∞,或 -∞,返回 Result(1)
  4. 计算 sign(Result(1)) * floor(abs(Result(1)))
  5. 返回 Result(4)

ToString

将其参数转换为字符串类型的值

输入类型 结果
Undefined “undefined”
Null “null”
Boolean 如果参数是 true,那么结果为 “true”。如果参数是 false,那么结果为 “false”
Number
String 结果等于输入的参数(不转换)
Object 1. 调用 ToPrimitive( 输入参数 , 暗示 字符串类型)。 2. 调用 ToString(Result(1))。 3. 返回 Result(2)。

ToObject

将其参数转换为对象类型的值

输入类型 结果
Undefined 抛出 TypeError 异常
Null 抛出 TypeError 异常
Boolean 创建一个新的Boolean对象,其 [[PrimitiveValue]]属性被设为该布尔值的值
Number 创建一个新的Number对象,其[[PrimitiveValue]]属性被设为该布尔值的值
String 创建一个新的String对象,其 [[PrimitiveValue]] 属性被设为该布尔值的值
Object 结果是输入的参数(不转换)

表达式

主值表达式

this关键字

this 关键字执行为当前执行环境的 ThisBinding

标识符引用
字面量引用
数组初始化
对象初始化
分组表达式

一元运算符

delete 运算符
typeof 运算符
val 类型 结果
Undefined “Undefined”
Null “null”
Boolean “boolean”
Number “number”
String “string”
Object(原生,且没有实现call) “object”
Object(原生或者宿主实现call) “function”

语句

if 语句

1
if ( Expression ) Statement else Statement

迭代语句

do-while 语句

循环至少执行一次,即便条件为 false,因为代码块是在条件语句判断前执行。

1
2
3
4
5
6
7
8
9
10
do Statement while ( Expression )
var text = ""
var i = 0;
do {
text += "<br>数字为 " + i;
i++;
}
while (i < 5) {
document.getElementById("demo").innerHTML = text;
}
while语句

while 循环会在指定条件为真时循环执行代码块。

1
while ( Expression ) Statement
for 语句
1
for ( ExpressionNoInopt ; Expressionopt ; Expressionopt) Statement
for-in 语句
1
2
3
4
5
6
7
8
9
for ( LeftHandSideExpression in Expression ) Statement
var person = {fname:"John", lname:"Doe", age:25};
var text = "";
var x;
for (x in person) {
text += person[x];
}

结果:John Doe 25

总结:for/in 语句用于循环对象属性。循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作。

  • for - 循环代码块一定的次数
  • for/in - 循环遍历对象的属性
  • while - 当指定的条件为 true 时循环指定的代码块
  • do/while - 同样当指定的条件为 true 时循环指定的代码块

注意:不要使用 for/in 语句来循环数组的索引,你可以使用 for 语句替代。

continue 语句

continue 语句中断循环中的迭代,如果出现了指定的条件,然后继续循环中的下一个迭代。 该例子跳过了值 3

1
2
3
4
5
6
continue;
for (i=0;i<=10;i++)
{
if (i==3) continue;
x=x + "The number is " + i + "<br>";
}

break 语句

break 语句可用于跳出循环

1
2
3
4
5
for (i=0;i<10;i++)
{
if (i==3) break;
x=x + "The number is " + i + "<br>";
}

总结:break 语句可用于跳出循环。

continue 语句跳出循环后,会继续执行该循环之后的代码(如果有的话)

return 语句

return 语句会终止函数的执行并返回函数的值

1
2
3
4
return ;
function myFunction() {
return Math.PI;
}

with 语句

1
with ( Expression ) Statement

switch 语句

switch 语句用于基于不同的条件来执行不同的动作。

switch 语句是 JavaScript 条件语句的一部分,用于根据不同的条件执行不同的动作。 使用 switch 从多个语句块中选择一个执行。

switch 语句计算每个表达式。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。

switch 语句通常与 break 或 default 关键字一起使用。两者都是可选的

break 关键字用于跳出switch代码块。会终止switch代码块的执行。 如果忽略该关键字,swith 语句的下一个代码块会被执行。

default 关键字 来规定匹配不存在时做的事情。 default 关键字在 switch 语句中只能出现一次。虽然是可选参数,但是建议都使用该参数,在不是我们期望的情况下,可以使用它输出信息。

1
2
3
4
5
6
7
8
9
10
switch(expression) {
case n:
代码块
break;
case n:
代码块
break;
default:
默认代码块
}

throw 语句

throw [no LineTerminator here] Expression ;

检测输入变量的值。如果值是错误的,会抛出一个异常(err)

异常 (err) 通过 catch 语句捕获并自定义输出错误信息

  • throw 语句抛出一个错误
  • 当错误发生时, JavaScript 会停止执行并抛出错误信息
  • 异常可以是 JavaScript 字符串、数字、逻辑值或对象
1
2
3
4
5
6
7
8
9
try { 
if(x == "") throw "is Empty";
if(isNaN(x)) throw "not a number";
if(x > 10) throw "too high";
if(x < 5) throw "too low";
}
catch(err) {
message.innerHTML = "Input " + err;
}

debugger

debugger 语句用于停止执行 JavaScript,并调用 (如果可用) 调试函数

使用 debugger 语句类似于在代码中设置断点

通常,你可以通过按下 F12 开启调试工具, 并在调试菜单中选择 “Console”

对象

全局对象

唯一的全局对象建立在控制进入任何执行环境之前

全局对象值属性
NaN

NaN 的值是 NaN

Infinity

Infinity 的值是 +∞

undefined

undefined 的值是 undefined

全局对象的函数属性
eval (x)

eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行

如果参数是一个表达式,eval() 函数将执行表达式。如果参数是Javascript语句,eval()将执行 Javascript 语句。

parseInt (string , radix)
参数 描述
string 必需。要被解析的字符串。
radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
  • 如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
  • 如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
  • 如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
parseFloat (string)

parseFloat() 函数可解析一个字符串,并返回一个浮点数。

该函数指定字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。

isNaN(value)

isNaN() 函数用于检查其参数是否是非数字值。

如果参数值为 NaN 或字符串、对象、undefined等非数字值则返回 true, 否则返回 false。

isFinite(value)

isFinite() 函数用于检查其参数是否是无穷大。

如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。

Number(object)

Number() 函数把对象的值转换为数字。

如果对象的值无法转换为数字,那么 Number() 函数返回 NaN。

object 可选。一个 JavaScript 对象。如果没有提供参数,则返回0。

String(object)

String() 函数把对象的值转换为字符串。

Object对象

Math 对象

Math 对象属性
属性 描述
E 返回算术常量 e,即自然对数的底数(约等于2.718)
LN2 返回 2 的自然对数(约等于0.693)
LN10 返回 10 的自然对数(约等于2.302)
LOG2E 返回以 2 为底的 e 的对数(约等于 1.4426950408889634)
LOG10E 返回以 10 为底的 e 的对数(约等于0.434)
PI 返回圆周率(约等于3.14159)
SORT1 2 返回 2 的平方根的倒数(约等于 0.707)
SORT2 返回 2 的平方根(约等于 1.414)
Math 对象方法
方法 描述
abs(x) 返回
ceil(x) 对数进行上舍入
exp(x) 返回 E^x 的指数
floor(x) 对x进行下舍入
max(x,y,z,…n) 返回 x,y,z,…,n 中的最高值
min(x,y,z,…n) 返回 x,y,z,…,n中的最低值
pow(x,y) 返回 x 的 y 次幂
random() 返回0-1之间的随机数
round(x) 四舍五入

Array 对象

数组属性

属性 描述
constructor 返回创建数组对象的原型函数
length 设置或返回数组元素的个数
prototype 允许向数组对象添加属性或方法

Array 对象属性

方法 描述
concat() 连接两个或更多的数组,并返回结果。
every() 用于检测数组所有元素是否都符合指定条件(通过函数提供)如果有一个元素不满足,返回false,所有元素都满足,则返回true。
fill() 将一个固定值替换数组中所有的元素。
filter() 创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的元素。
find() 返回通过测试(函数内判断)的数组的第一个元素的值
forEach() 调用数组的每个元素,并将元素传递给回调函数
isArray() 判断一个对象是否为数组, Array.isArray(array)
map() 返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
pop() 删除数组的最后一个元素并返回删除的元素
reverse() 反转数组的元素顺序
shift() 删除并返回数组的第一个元素
slice() 选取数组的的一部分,并返回一个新数组,不会改变原始数组
splice() 插入、删除或替换数组的元素,会改变原始数组
unshift() 向数组的开头添加一个或更多元素,并返回新的长度,将改变数组的数目

Date 对象

用于处理日期和时间

1
2
3
4
5
创建 Date 对象方法
$ var d = new Date();
$ var d = new Date(milliseconds);
$ var d = new Date(dateString);
$ var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);
Date 对象方法
方法 描述
getDate() 从Date对象返回一个月的某一天(1-31)
getDay() 从Date对象返回一周中的某一天(0-6)
getFullYear() 以四位数返回年份
getHours() 返回小时(0-23)
getMilliseconds() 返回毫秒(0-999)
getMinutes() 返回分钟(0-59)
getMonth() 返回月份(0-11)
getTime() 返回从1970年1月1日至今的毫秒数
getSeconds() 返回秒数(0-59)
parse() 返回 1970/1/1 午夜距离指定日期时间的毫秒数
setDate() 用于设置一个月的某一天
valueOf 返回 Date 对象的原始值原始值返回1970年1月1日午夜以来的毫秒数!

Number 对象

Number 对象属性
属性 描述
constructor 返回对创建此对象的 Number 函数的引用
MAX_VALUE 可表示的最大数
MIN_VALUE 可表示的最小数
NAGATIVE_INFINITY 负无穷大,溢出时返回该数值
NaN 非数字值
POSITIVE_INFINITITY 正无穷大,溢出时返回该数值
prototype 允许向对象添加属性和方法
Number 对象方法
方法 描述
toExponential() 将对象的值转换为指数计数法
toFixed() 四舍五入为指定小数位数的数字
toPrecision() 对象的值超出指定位数时转换为指数计数法
toString() 转换为字符串
valueOf() 返回一个 Number 对象的基本数字值

RegExp 对象

正则表达式用于对字符串模式匹配及检索替换,是对字符串执行模式匹配的强大工具

1
2
3
4
语法:
var patt=new RegExp(pattern,modifiers);
或者
var patt=/pattern/modifiers;
  • pattern(模式) 描述了表达式的模式
  • modifiers(修饰符) 用于指定全局匹配、区分大小写的匹配和多行匹配
1
2
3
var re = new RegExp("\\w+");
等价
var re = /\w+/;
修饰符 描述
i 执行对大小写不敏感
g 执行全局匹配
m 执行多行匹配
方括号

用于查找某个范围内的字符

表达式 描述
[abc] 查找方括号之间
[^abc] 查找任何不在方括号之间的字符
[0-9] 查找任何从0至9的数字
[a-z] 查找任何从小写a到小写z的字符
[A-Z] 查找任何从大写A到大写Z的字符
(red\ blue\ green) 查找任何给定的选项
元字符

拥有特殊含义的字符

元字符 描述
. 查找单个字符,除了换行符和
\w 查找单词字符,单词字符包括:a-z、A-Z、0-9,以及下划线, 包含 _ (下划线) 字符
\W 查找非单词字符
\d 查找数字
\D 查找非数字字符
\s 查找空白字符
\S 查找非空白字符
\b 匹配单词边界
\B 匹配非单词边界
\0 查找null字符
\n 查找换行符
\f 查找换页符
\r 查找回车符
\t 查找制表符
量词
量词 描述
n+ 匹配任何包含至少一个n的字符串
n* 匹配任何包含零个或者多个n的字符串
n? 匹配任何包含零个或者一个n的字符串
n{X} 匹配包含 X 个 n 的序列的字符串
n{X,} X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配
n{X,Y} X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配
n$ 匹配任何以n结尾的字符串
^n 匹配任何以n开头的字符串
?=n 匹配任何其后紧接指定字符串 n 的字符串
?!n 匹配任何其后没有紧接指定字符串 n 的字符串
对象方法
方法 描述
exec() 检索字符串中指定的值。返回找到的值,并确定其位置。var result=patt.exec(str);
test() 检索字符串中指定的值。返回 true 或 false。var result=patt.test(str);
toString() 返回正则表达式的字符串。
支持正则表达式的 String 对象的方法
方法 描述
search() 检索与正则表达式相匹配的值。如果没有找到任何匹配的子串,则返回 -1。var n=str.search(“Runoob”);
match() 找到一个或多个正则表达式的匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。string.match(regexp)
replace() 在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。string.replace(searchvalue,newvalue)
split() 用于把一个字符串分割成字符串数组。string.split(separator,limit)

Hexo 搭建博客

Posted on 2018-09-28

系统环境配置

1
2
Node.js
Git

安装Hexo

1
2
3
4
5
6
7
$ cd hexo
$ npm install hexo-cli -g
$ hexo into blog
$ cd blog
$ npm install
$ hexo g || hexo generate
$ hexo s || hexo server

Hexo 常用命令
hexo g 生成静态文件,会在当前目录下生成一个新的叫做public的文件夹
hexo s 启动本地web服务,用于博客的预览
hexo deploy (hexo d) 部署播客到远端

1
2
$ hexo new 'postName' --- 新建文章
$ hexo new page "pageName" --- 新建页面

常用简写

1
2
3
4
$ hexo n == hexo new
$ hexo g == hexo generate
$ hexo s == hexo server
$ hexo d == hexo deploy

目前安装所用的本地环境如下:(可以通过hexo -v查看)

Hexo 主题设置

安装主题

1
2
$ hexo clean
$ git clone https://github.com/iissnan/hexo-theme-next.git themes/next

启用主题

修改Hexo目录下的_config.yml配置文件中的theme属性,将其设置为next

更新主题

1
2
3
4
$ cd themes/next
$ git pull
$ hexo g # 生成
$ hexo s # 启动本地web服务器

部署Hexo到Github Pages

使用hexo deploy部署

1
2
3
4
5
修改Hexo目录下的_config.yml配置文件
deploy:
type: git
repo: git@github.com:username/username.github.io.git
branch: master

需要提前安装一个扩展

1
$ npm install hexo-deployer-git --save

然后在命令行中执行

1
$ hexo d

使用git命令行部署

1
2
$ cd hexo/blog
$ git clone https://github.com/username/username.github.io.git .deploy/username.github.io

将github上创建的博客克隆到本地,新建一个目录叫做.deploy用于存放克隆的代码

创建一个deploy脚本文件

1
2
3
4
5
6
$ hexo generate
$ cp -R public/ .deploy/username.github.io
$ cd .deploy/username.github.io
$ git add .
$ git commit -m “update”
$ git push origin master

Hexo 配置主题

主题配置在themes文件下_config.yml

参考链接

手把手教你使用Hexo + Github Pages搭建个人独立博客
我是如何利用Github Pages搭建起我的博客,细数一路的坑
hexo你的博客

Cherry

4 posts
RSS
© 2019 Cherry
Powered by Hexo
|
Theme — NexT.Mist v5.1.4