浅尝ES6
Class和普通构造函数
class为es6的语法糖;
总的来说class的语法更接近面向对象,更加已读,对于后端开发来说更容易上手;
class底层原理还是prototype;
普通构造函数实现
1 |
|
class实现
1 |
|
继承
普通继承实现
1 |
|
class实现
1 |
|
var与let作用域
let
在es6中用来声明变量,用法类型与var
-
var
的作用域为函数上下文或全局上下文; -
let
的作用域由最近的一对{}
所限定,及只在局部有效; -
var
变量可以重复声明,但是let
变量重复声明会报错(SyntaxError); -
let
适合在循环中声明变量;
变量的解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
数组的解构赋值
1 |
|
对象的解构赋值
1 |
|
字符串的解构赋值
1 |
|
函数参数的解构赋值
1 |
|
变量的解构赋值用途
-
交换变量的值
1
[x, y] = [y, x];
-
从函数返回多个值
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 返回一个数组
function example() {
return [1, 2, 3];
}
var [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
var { foo, bar } = example(); -
函数参数的定义
1
2
3
4
5
6
7// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1}); -
提取JSON数据
1
2
3
4
5
6
7
8
9var jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number); -
函数参数的默认值
1
2
3
4
5
6
7
8
9
10
11jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
}) {
// ... do stuff
}; -
遍历Map结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
} -
加载模块的指定方法
1
const { SourceMapConsumer, SourceNode } = require("source-map");
字符串的扩展
实用方法
-
includes():返回布尔值,表示是否找到了参数字符串;
-
startsWith():返回布尔值,表示参数字符串是否在源字符串的头部;
-
endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部;
-
repeat():方法返回一个新字符串,表示将原字符串重复
n
次,若n为小数则向下取整,若n为负数或报错; -
padStart(),padEnd():字符串补全长度
1
2
3
4
5
6
7
8
9'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
// 省略第二个参数,则会用空格补全长度
'x'.padStart(4) // ' x'
'x'.padEnd(4) // 'x '
模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
模板字符串中嵌入变量,需要将变量名写在
${}
之中。大括号内部可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
模板字符串之中还能调用函数。
1 |
|
数组的扩展
-
Array.from():将类似数组的对象(array-like object)和可遍历(iterable)的对象转化为数组
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
28let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
// 常见的类似数组的对象是DOM操作返回的NodeList集合,以及函数内部的arguments对象
// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) {
console.log(p);
});
// arguments对象
function foo() {
var args = Array.from(arguments);
// ...
}
// 值得提醒的是,扩展运算符(...)也可以将某些数据结构转为数组
// arguments对象
function foo() {
var args = [...arguments];
}
// NodeList对象
[...document.querySelectorAll('div')] -
find()和findIndex():用于找出第一个符合条件的数组成员或下标
1
2
3
4[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
// find方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组 -
fill():填充数组
-
includes():法返回一个布尔值,表示某个数组是否包含给定的值
扩展运算符
扩展运算符(spread)是三个点(
...
),将一个数组转为用逗号分隔的参数序列
用于函数调用
1 |
|
替代数组的apply方法
1 |
|
扩展运算符的应用
-
合并数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var 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
11const [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
2var dateFields = readDateFields(database);
var d = new Date(...dateFields); -
字符串
1
2
3// 扩展运算符还可以将字符串转为真正的数组
[...'hello']
// [ "h", "e", "l", "l", "o" ] -
实现了Iterator接口的对象
1
2
3// 任何Iterator接口的对象,都可以用扩展运算符转为真正的数组
var nodeList = document.querySelectorAll('div');
var array = [...nodeList]; -
Map和Set结构,Generator函数
1
2
3
4
5
6
7let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]
箭头函数
ES6允许使用“箭头”(
=>
)定义函数。
基本用法
1 |
|
使用注意点
- 函数体内的
this
对象,就是定义时所在的对象,而不是使用时所在的对象 - 不可以当作构造函数,也就是说,不可以使用
new
命令,否则会抛出一个错误 - 不可以使用
arguments
对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替 - 不可以使用
yield
命令,因此箭头函数不能用作Generator函数
对象的拓展
Object.is()
它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
1 |
|
Object.assign()
Object.assign
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。类似于jQuery中的$.extend()方法。
1 |
|
常见用法
-
为对象添加属性
1
2
3
4
5class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
} -
为对象添加方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
}; -
克隆对象
1
2
3function clone(origin) {
return Object.assign({}, origin);
} -
合并多个对象
1
2const merge =
(...sources) => Object.assign({}, ...sources); -
为属性指定默认值
1
2
3
4
5
6
7
8const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
options = Object.assign({}, DEFAULTS, options);
}
属性的遍历
- for…in
- Object.keys(obj)
- Object.getOwnPropertyNames(obj)
- Object.getOwnPropertySymbols(obj)
- Reflect.ownKeys(obj)