ES6学习笔记

前言

整理一些ES6标准的学习笔记,虽然网上已经很多了,还是想写一些hh
文中有大部分参考了阮一峰老师的ECMAScript 6入门

正文

块级作用域、let和const

ES6新加入了块级作用域,一个花括号{}就代表一个独立的作用域。简单来说被作用域嵌套时外层代码不会被内层代码块影响。看个简单的例子

1
2
3
4
5
6
7
8
9
10
11
function 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
8
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
//result: 10

1
2
3
4
5
6
7
8
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6]();
//result: 6

const命令的作用和限制呢,和其他语言差不多,感觉没啥好说的hh

还有就是varlet、const声明变量对于全局对象属性的不同之处

  1. var命令和function命令声明的全局变量,属于全局对象的属性
  2. let命令、const命令、声明的全局变量,不属于全局对象的属性。

###变量的解构赋值
ES6允许在对变量进行赋值时,按照一定模式从数组和对象中提取值进行赋值,称为解构。解构只能用于数组或对象。

  • 对数组的解构赋值,允许指定默认值
  • 对对象的解构赋值,属性没有次序,要求变量与属性同名(sigoyi)
    1
    2
    3
    let [foo, [[bar], baz]] = [1, [[2], 3]];
    let [x, y='b'] = ['a', undefined]; // x='a', y='b'
    let { foo, bar } = { foo: "aaa", bar: "bbb" };

字符串的扩展——模板字符串

模板字符串是增强版的字符串,用反引号(`)标识。

  1. 当作普通字符串使用
  2. 定义多行字符串
  3. 在字符串中嵌入变量
    使用规则如下:
  4. 在模板字符串中嵌入变量,需要将变量名写在${}之中。
  5. 如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。
  6. 大括号内部可以进行运算,以及引用对象属性,其中还能调用函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 多行字符串
console.log(`string text line 1
string text line 2`);

// 字符串中嵌入变量
var name = "Bob", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);

//对象属性
var obj = {x: 1, y: 2};
console.log(`${obj.x + obj.y}`);

//函数调用
function fn() {
return "Hello World";
}
console.log(`foo : ${fn()}`);

其实字符串扩展还有一部分是对字符串处理的增强,多是与字符编码相关的,博主也不是特别熟,这里就不多说了,有兴趣可以参考字符串的扩展

数值的扩展

参考数值的扩展(太懒不讲)

数组的扩展

ES6中提供了数组推导的方法即利用现有数组生成新数组的简化写法for...of,允许多重循环

1
2
3
4
5
6
7
var 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
    17
    for (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
    6
    onsole.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>]

函数的扩展

  1. ES6允许为函数的参数设置默认值,使用=形式直接写在参数定义的后面
    • 指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。
    • 参数默认值所处的作用域,不是全局作用域,而是函数作用域。
  2. rest运算符...,与扩展运算符为互逆操作,即...+变量名形式与...+数组形式互逆...变量名必须作为最后一个参数且函数的length属性不包括rest参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function add(...values) {
    let sum = 0;

    for (var val of values) {
    sum += val;
    }

    return sum;
    }

    add(2, 5, 3) // 10

    (function(a, ...b) {}).length // 1
  3. 箭头函数=>,大家都知道吧hhh,不说了

对象扩展 Symbol、Proxy

Symbol

Symbol是ES6引入的一种新的原始数据类型,表示独一无二的值。目的是从根本上防止属性名的冲突。
Symbol用于对象的属性名,就能保证不会出现同名的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var 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
12
var 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 函数

结语

这篇好像贴别人的参考有点多哈
没关系,重在参与~

用钱砸我