前言
整理一些ES6标准的学习笔记,虽然网上已经很多了,还是想写一些hh
文中有大部分参考了阮一峰老师的ECMAScript 6入门
正文
块级作用域、let和const
ES6新加入了块级作用域,一个花括号{}
就代表一个独立的作用域。简单来说被作用域嵌套时外层代码不会被内层代码块影响。看个简单的例子1
2
3
4
5
6
7
8
9
10
11function f() { console.log('I am outside!'); }
(function () {
if(false) {
// 重复声明一次函数f
function f() { console.log('I am inside!'); }
}
f();
}());
//ES5 result: I am inside!
//ES6 result: I am outside!
再就是let
命令了,let
命令的作用就是其所声明的变量,仅在其所在代码块内有效。需要注意的是,let不会像var一样声明提前,只能在定义之后使用,之前使用会抛出ReferenceError并且不允许在相同作用域内,重复声明同一个变量。因此,不能在函数内部重新声明参数。1
2
3
4
5
6
7
8var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
//result: 10
1 | var a = []; |
const
命令的作用和限制呢,和其他语言差不多,感觉没啥好说的hh
还有就是var
和let、const
声明变量对于全局对象属性的不同之处
- var命令和function命令声明的全局变量,属于全局对象的属性
- let命令、const命令、声明的全局变量,不属于全局对象的属性。
###变量的解构赋值
ES6允许在对变量进行赋值时,按照一定模式从数组和对象中提取值进行赋值,称为解构。解构只能用于数组或对象。
- 对数组的解构赋值,允许指定默认值
- 对对象的解构赋值,属性没有次序,要求变量与属性同名(sigoyi)
1
2
3let [foo, [[bar], baz]] = [1, [[2], 3]];
let [x, y='b'] = ['a', undefined]; // x='a', y='b'
let { foo, bar } = { foo: "aaa", bar: "bbb" };
字符串的扩展——模板字符串
模板字符串是增强版的字符串,用反引号(`)
标识。
- 当作普通字符串使用
- 定义多行字符串
- 在字符串中嵌入变量
使用规则如下: - 在模板字符串中嵌入变量,需要将变量名写在${}之中。
- 如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。
- 大括号内部可以进行运算,以及引用对象属性,其中还能调用函数。
1 | // 多行字符串 |
其实字符串扩展还有一部分是对字符串处理的增强,多是与字符编码相关的,博主也不是特别熟,这里就不多说了,有兴趣可以参考字符串的扩展
数值的扩展
参考数值的扩展(太懒不讲)
数组的扩展
ES6中提供了数组推导的方法即利用现有数组生成新数组的简化写法for...of
,允许多重循环1
2
3
4
5
6
7var a1 = [1, 2, 3, 4];
var a2 = [for (i of a1) i * 2];
a2 // [2, 4, 6, 8]
var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
[for (year of years) if (year > 2000 && year < 2010) year];
// [ 2006]
还有一些额外的数组处理方法
Array.from
可以将两类对象转为真正的数组:类似数组的对象(array-like object,有length属性)和可遍历(iterable)的对象。Array.of
可将一组值转化为数组对象。- 实例方法
copyWithin
可将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。 - 实例的
find
方法,用于找出第一个符合条件的数组成员。接受一个回调函数(value, index, arr)=>{}
作为参数,对每个元素执行该函数,返回第一个返回值为true
的成员。 - 实例的
findIndex
方法与find
类似,返回成员下标。 数组实例的
entries()
,keys()
和values()
方法,返回数组的遍历器对象,keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"扩展运算符
...
,简而言之扩展运算符可以将数组扩展为以逗号分割的参数列表1
2
3
4
5
6onsole.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
函数的扩展
- ES6允许为函数的参数设置默认值,使用=形式直接写在参数定义的后面
- 指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。
- 参数默认值所处的作用域,不是全局作用域,而是函数作用域。
rest运算符
...
,与扩展运算符为互逆操作,即...
+变量名形式与...
+数组形式互逆,...变量名
必须作为最后一个参数且函数的length属性不包括rest参数1
2
3
4
5
6
7
8
9
10
11
12
13function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
(function(a, ...b) {}).length // 1箭头函数
=>
,大家都知道吧hhh,不说了
对象扩展 Symbol、Proxy
Symbol
Symbol
是ES6引入的一种新的原始数据类型,表示独一无二的值。目的是从根本上防止属性名的冲突。
将Symbol
用于对象的属性名,就能保证不会出现同名的属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var mySymbol = Symbol();
// 第一种写法
var a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
var a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
var a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
需要注意的是,Symbol值作为对象属性名时,不能用点运算符
具体Symbol.for()、Symbol.keyFor()
方法的说明可以参考Symbol
Proxy
可以简单理解为为对象的访问增加一层代理,对对象的访问都会先经过代理层的拦截
给出一个简单的例子1
2
3
4
5
6
7
8
9
10
11
12var person = {
name: "张三"
};
var proxy = new Proxy(person, {
get: function(target, property) {
return property in target ? target[property] : "不存在的";
}
});
proxy.name // "张三"
proxy.title // "不存在的"
具体Proxy
可拦截的操作可参考Proxy概述
Generator函数
还是贴一下参考资料好了,人家写的是真好Generator 函数
结语
这篇好像贴别人的参考有点多哈
没关系,重在参与~