0
点赞
收藏
分享

微信扫一扫

【ES】150-重温基础:ES6系列(一)

【ES】150-重温基础:ES6系列(一)_字符串

ES6系列目录

  • 1 let 和 const命令
  • 2 变量的解构赋值
  • 3 字符串的拓展
  • 4 正则的拓展
  • 5 数值的拓展
  • 6 函数的拓展
  • 7 数组的拓展
  • 8 对象的拓展
  • 9 Symbol
  • 10 Set和Map数据结构
  • 11 Proxy
  • 12 Promise对象
  • 13 Iterator和 for...of循环
  • 14 Generator函数和应用
  • 15 Class语法和继承
  • 16 Module语法和加载实现


所有整理的文章都收录到我《Cute-JavaScript》系列文章中,访问地址:http://js.pingan8787.com


1 let 和 const命令

在ES6中,我们通常实用 ​let​ 表示变量, ​const​ 表示常量,并且 ​let​​ 和 ​const​ 都是块级作用域,且在当前作用域有效不能重复声明。

1.1 let 命令

let​​ 命令的用法和 ​var​​ 相似,但是 ​let​​ 只在所在代码块内有效。
基础用法

  1. {
  2.    let a = 1;
  3.    let b = 2;
  4. }

并且 ​let​ 有以下特点:

  • 不存在变量提升:
    在ES6之前,我们 ​​var​ 声明一个变量一个函数,都会伴随着变量提升的问题,导致实际开发过程经常出现一些逻辑上的疑惑,按照一般思维习惯,变量都是需要先声明后使用。
  1. // var
  2. console.log(v1); // undefined
  3. var v1 = 2;
  4. // 由于变量提升 代码实际如下
  5. var v1;
  6. console.log(v1)
  7. v1 = 2;

  8. // let
  9. console.log(v2); // ReferenceError
  10. let v2 = 2;
  • 不允许重复声明:
    ​​let​​ 和 ​​const​​ 在相同作用域下,都不能重复声明同一变量,并且不能在函数内重新声明参数
  1. // 1. 不能重复声明同一变量
  2. // 报错
  3. function f1 (){
  4.    let a = 1;
  5.    var a = 2;
  6. }
  7. // 报错
  8. function f2 (){
  9.    let a = 1;
  10.    let a = 2;
  11. }

  12. // 2. 不能在函数内重新声明参数
  13. // 报错
  14. function f3 (a1){
  15.    let a1;
  16. }
  17. // 不报错
  18. function f4 (a2){
  19.    {
  20.        let a2
  21.    }
  22. }

1.2 const 命令

const​ 声明一个只读常量
基础用法

  1. const PI = 3.1415926;
  2. console.log(PI);  // 3.1415926

注意点

  • const​ 声明后,无法修改值;
  1. const PI = 3.1415926;
  2. PI = 3;
  3. // TypeError: Assignment to constant variable.
  • const​ 声明时,必须赋值;
  1. const a ;
  2. // SyntaxError: Missing initializer in const declaration.
  • const​​ 声明的常量, ​​let​​ 不能重复声明;
  1. const PI = 3.1415926;
  2. let PI = 0;  
  3. // Uncaught SyntaxError: Identifier 'PI' has already been declared

2 变量的解构赋值

解构赋值概念:在ES6中,直接从数组和对象中取值,按照对应位置,赋值给变量的操作。

2.1 数组

基础用法

  1. // ES6 之前
  2. let a = 1;
  3. let b = 2;

  4. // ES6 之后
  5. let [a, b] = [1, 2];

本质上,只要等号两边模式一致,左边变量即可获取右边对应位置的值,更多用法:

  1. let [a, [[b], c]] = [1, [[2], 3]];
  2. console.log(a, b, c); // 1, 2, 3

  3. let [ , , c] = [1, 2, 3];
  4. console.log(c);       // 3

  5. let [a, , c] = [1, 2, 3];
  6. console.log(a,c);     // 1, 3

  7. let [a, ...b] = [1, 2, 3];
  8. console.log(a,b);     // 1, [2,3]

  9. let [a, b, ..c.] = [1];
  10. console.log(a, b, c); // 1, undefined, []

注意点

  • 如果解构不成功,变量的值就等于 ​undefined​。
  1. let [a] = [];     // a => undefined
  2. let [a, b] = [1]; // a => 1 , b => undefined
  • 当左边模式多于右边,也可以解构成功。
  1. let [a, b] = [1, 2, 3];
  2. console.log(a, b); // 1, 2
  • 两边模式不同,报错。
  1. let [a] = 1;
  2. let [a] = false;
  3. let [a] = NaN;
  4. let [a] = undefined;
  5. let [a] = null;
  6. let [a] = {};

指定解构的默认值
基础用法

  1. let [a = 1] = [];      // a => 1
  2. let [a, b = 2] = [a];  // a => 1 , b => 2

特殊情况:

  1. let [a = 1] = [undefined]; // a => 1
  2. let [a = 1] = [null];      // a => null

右边模式对应的值,必须严格等于 ​undefined​​,默认值才能生效,而 ​null​​不严格等于 ​undefined​。

2.2 对象的解构赋值

与数组解构不同的是,对象解构不需要严格按照顺序取值,而只要按照变量名去取对应属性名的值,若取不到对应属性名的值,则为 ​undefined​ 。

基础用法

  1. let {a, b} = {a:1, b:2};  // a => 1 , b => 2
  2. let {a, b} = {a:2, b:1};  // a => 2 , b => 1
  3. let {a} = {a:3, b:2, c:1};// a => 3
  4. let {a} = {b:2, c:1};     // a => undefined

注意点

  • 变量名属性名不一致,则需要修改名称。
  1. let {a:b} = {a:1, c:2};
  2. // error: a is not defined
  3. // b => 1

对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
上面代码中, ​​a​​ 是匹配的模式, ​b​​才是变量。真正被赋值的是变量 ​b​​,而不是模式 ​a​。

  • 对象解构也支持嵌套解构
  1. let obj = {
  2.    a:[ 1, { b: 2}]
  3. };
  4. let {a, a: [c, {b}]} = obj;
  5. // a=>[1, {b: 2}], b => 2, c => 1

指定解构的默认值

  1. let {a=1} = {};        // a => 1
  2. let {a, b=1} = {a:2};  // a => 2, b => 1

  3. let {a:b=3} = {};      // b => 3
  4. let {a:b=3} = {a:4};   // b = >4
  5. // a是模式,b是变量 牢记

  6. let {a=1} = {a:undefined};  // a => 1
  7. let {a=1} = {a:null};   // a => null
  8. // 因为null与undefined不严格相等,所以赋值有效
  9. // 导致默认值1不会生效。

2.3 字符串的解构赋值

字符串的解构赋值中,字符串被转换成了一个类似数组的对象基础用法

  1. const [a, b, c, d, e] = 'hello';
  2. a // "h"
  3. b // "e"
  4. c // "l"
  5. d // "l"
  6. e // "o"

  7. let {length:len} = 'hello';// len => 5

2.4 数值和布尔值的解构赋值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于 ​undefined​​和 ​null无法转为对象,所以对它们进行解构赋值,都会报错。

  1. // 数值和布尔值的包装对象都有toString属性
  2. let {toString: s} = 123;
  3. s === Number.prototype.toString // true
  4. let {toString: s} = true;
  5. s === Boolean.prototype.toString // true

  6. let { prop: x } = undefined; // TypeError
  7. let { prop: y } = null;      // TypeError

2.5 函数参数的解构赋值

基础用法

  1. function fun ([a, b]){
  2.    return a + b;
  3. }
  4. fun ([1, 2]); // 3

指定默认值的解构:

  1. function fun ({a=0, b=0} = {}){
  2.    return [a, b];
  3. }
  4. fun ({a:1, b:2}); // [1, 2]
  5. fun ({a:1});      // [1, 0]
  6. fun ({});         // [0, 0]
  7. fun ();           // [0, 0]

  8. function fun ({a, b} = {a:0, b:0}){
  9.    return [a, b];
  10. }
  11. fun ({a:1, b:2}); // [1, 2]
  12. fun ({a:1});      // [1, undefined]
  13. fun ({});         // [undefined, undefined]
  14. fun ();           // [0, 0]

2.6 应用

  • 交换变量的值:
  1. let a = 1,b = 2;
  2. [a, b] = [b, a]; // a =>2 , b => 1
  • 函数返回多个值:
  1. // 返回一个数组
  2. function f (){
  3.    return [1, 2, 3];
  4. }
  5. let [a, b, c] = f(); // a=>1, b=>2, c=>3

  6. // 返回一个对象
  7. function f (){
  8.    return {a:1, b:2};
  9. }
  10. let {a, b} = f();    // a=>1, b=>2
  • 快速对应参数: 快速的将一组参数与变量名对应。
  1. function f([a, b, c]) {...}
  2. f([1, 2, 3]);

  3. function f({a, b, c}) {...}
  4. f({b:2, c:3, a:1});
  • 提取JSON数据
  1. let json = {
  2.    name : 'leo',
  3.    age: 18
  4. }
  5. let {name, age} = json;
  6. console.log(name,age); // leo, 18
  • 遍历Map结构:
  1. const m = new Map();
  2. m.set('a', 1);
  3. m.set('b', 2);
  4. for (let [k, v] of m){
  5.    console.log(k + ' : ' + v);
  6. }
  7. // 获取键名
  8. for (let [k] of m){...}
  9. // 获取键值
  10. for (let [,k] of m){...}
  • 输入模块的指定方法: 用于按需加载模块中需要用到的方法。
  1. const {log, sin, cos} = require('math');

3 字符串的拓展

3.1 includes(),startsWith(),endsWith()

在我们判断字符串是否包含另一个字符串时,ES6之前,我们只有 ​typeof​方法,ES6之后我们又多了三种方法:

  • includes():返回布尔值,表示是否找到参数字符串
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
  1. let a = 'hello leo';
  2. a.startsWith('leo');   // false
  3. a.endsWith('o');       // true
  4. a.includes('lo');      // true

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

  1. let a = 'hello leo';
  2. a.startsWith('leo',1);   // false
  3. a.endsWith('o',5);       // true
  4. a.includes('lo',6);      // false

endsWith​​ 是针对前 ​n​​ 个字符,而其他两个是针对从第 ​n​个位置直到结束。

3.2 repeat()

repeat​​方法返回一个新字符串,表示将原字符串重复 ​n​​次。
基础用法

  1. 'ab'.repeat(3);        // 'ababab'
  2. 'ab'.repeat(0);        // ''

特殊用法:

  • 参数为 ​小数​,则取整
  1. 'ab'.repeat(2.3);      // 'abab'
  • 参数为 ​负数​​或 ​​Infinity​​,则报错
  1. 'ab'.repeat(-1);       // RangeError
  2. 'ab'.repeat(Infinity); // RangeError
  • 参数为 ​0到-1的小数​​或 ​​NaN​​,则取0
  1. 'ab'.repeat(-0.5);     // ''
  2. 'ab'.repeat(NaN);      // ''
  • 参数为 ​字符串​​,则转成 ​​数字​
  1. 'ab'.repeat('ab');     // ''
  2. 'ab'.repeat('3');      // 'ababab'

3.3 padStart(),padEnd()

用于将字符串头部尾部补全长度, ​padStart()​为头部补全, ​padEnd()​为尾部补全
这两个方法接收2个参数,第一个指定字符串最小长度,第二个用于补全的字符串
基础用法

  1. 'x'.padStart(5, 'ab');   // 'ababx'
  2. 'x'.padEnd(5, 'ab');     // 'xabab'

特殊用法:

  • 原字符串长度,大于或等于指定最小长度,则返回原字符串。
  1. 'xyzabc'.padStart(5, 'ab'); // 'xyzabc'
  • 用来补全的字符串长度和原字符串长度之和,超过指定最小长度,则截去超出部分的补全字符串。
  1. 'ab'.padStart(5,'012345'); // "012ab"
  • 省略第二个参数,则用 ​空格​补全。
  1. 'x'.padStart(4);           // '    x'
  2. 'x'.padEnd(4);             // 'x    '

3.4 模版字符串

用于拼接字符串,ES6之前:

  1. let a = 'abc' +
  2.    'def' +
  3.    'ghi';

ES6之后:

  1. let a = `
  2.    abc
  3.    def
  4.    ghi
  5. `

拼接变量: 在反引号(`)中使用 ​${}​包裹变量或方法。

  1. // ES6之前
  2. let a = 'abc' + v1 + 'def';

  3. // ES6之后
  4. let a = `abc${v1}def`

4 正则的拓展

4.1 介绍

在ES5中有两种情况。

  • 参数是字符串,则第二个参数为正则表达式的修饰符。
  1. let a = new RegExp('abc', 'i');
  2. // 等价于
  3. let a = /abx/i;
  • 参数是正则表达式,返回一个原表达式的拷贝,且不能有第二个参数,否则报错。
  1. let a = new RegExp(/abc/i);
  2. //等价于
  3. let a = /abx/i;

  4. let a = new RegExp(/abc/, 'i');
  5. //  Uncaught TypeError

ES6中使用:
第一个参数是正则对象,第二个是指定修饰符,如果第一个参数已经有修饰符,则会被第二个参数覆盖。

  1. new RegExp(/abc/ig, 'i');

4.2 字符串的正则方法

常用的四种方法: ​match()​​、 ​replace()​​、 ​search()​​和 ​split()​。

4.3 u修饰符

添加 ​u​​修饰符,是为了处理大于 ​uFFFF​的Unicode字符,即正确处理四个字节的UTF-16编码。

  1. /^\uD83D/u.test('\uD83D\uDC2A'); // false
  2. /^\uD83D/.test('\uD83D\uDC2A');  // true

由于ES5之前不支持四个字节UTF-16编码,会识别为两个字符,导致第二行输出 ​true​​,加入 ​u​​修饰符后ES6就会识别为一个字符,所以输出 ​false​。

注意:
加上 ​​u​修饰符后,会改变下面正则表达式的行为:

  • (1)点字符 点字符( ​.​)在正则中表示除了换行符以外的任意单个字符。对于码点大于 ​​0xFFFF​​的Unicode字符,点字符不能识别,必须加上 ​​u​​修饰符。
  1. var a = "𠮷";
  2. /^.$/.test(a);  // false
  3. /^.$/u.test(a); // true
  • (2)Unicode字符表示法 使用ES6新增的大括号表示Unicode字符时,必须在表达式添加 ​u​修饰符,才能识别大括号。
  1. /\u{61}/.test('a');      // false
  2. /\u{61}/u.test('a');     // true
  3. /\u{20BB7}/u.test('𠮷'); // true
  • (3)量词 使用 ​u​​修饰符后,所有量词都会正确识别码点大于 ​​0xFFFF​​的 Unicode 字符。
  1. /a{2}/.test('aa');    // true
  2. /a{2}/u.test('aa');   // true
  3. /𠮷{2}/.test('𠮷𠮷');  // false
  4. /𠮷{2}/u.test('𠮷𠮷'); // true
  • (4)i修饰符 不加 ​u​​修饰符,就无法识别非规范的 ​​K​​字符。
  1. /[a-z]/i.test('\u212A') // false
  2. /[a-z]/iu.test('\u212A') // true

检查是否设置 ​u​修饰符:使用 ​unicode​属性。

  1. const a = /hello/;
  2. const b = /hello/u;

  3. a.unicode // false
  4. b.unicode // true

4.4 y修饰符

y​​修饰符与 ​g​​修饰符类似,也是全局匹配,后一次匹配都是从上一次匹配成功的下一个位置开始。区别在于, ​g​修饰符只要剩余位置中存在匹配即可,而 ​y​修饰符是必须从剩余第一个开始。

  1. var s = 'aaa_aa_a';
  2. var r1 = /a+/g;
  3. var r2 = /a+/y;

  4. r1.exec(s) // ["aaa"]
  5. r2.exec(s) // ["aaa"]

  6. r1.exec(s) // ["aa"]  剩余 '_aa_a'
  7. r2.exec(s) // null

lastIndex​属性: 指定匹配的开始位置:

  1. const a = /a/y;
  2. a.lastIndex = 2;  // 从2号位置开始匹配
  3. a.exec('wahaha'); // null
  4. a.lastIndex = 3;  // 从3号位置开始匹配
  5. let c = a.exec('wahaha');
  6. c.index;          // 3
  7. a.lastIndex;      // 4

返回多个匹配
一个 ​​y​​修饰符对 ​match​​方法只能返回第一个匹配,与 ​g​修饰符搭配能返回所有匹配。

  1. 'a1a2a3'.match(/a\d/y);  // ["a1"]
  2. 'a1a2a3'.match(/a\d/gy); // ["a1", "a2", "a3"]

检查是否使用 ​y​修饰符
使用 ​​sticky​属性检查。

  1. const a = /hello\d/y;
  2. a.sticky;     // true

4.5 flags属性

flags​属性返回所有正则表达式的修饰符。

  1. /abc/ig.flags;  // 'gi'


【ES】150-重温基础:ES6系列(一)_赋值_02

举报

相关推荐

0 条评论