es6 提取数组对象一部分_【ES】150重温基础:ES6系列(一)

本文详细介绍了ES6中的新特性,包括let和const命令,变量的解构赋值,字符串的拓展如includes()、startsWith()、endsWith()方法,以及正则表达式的u和y修饰符。此外,还讲解了函数参数的解构赋值,以及在实际开发中的应用场景,如交换变量值、遍历Map结构和模块导入等。
摘要由CSDN通过智能技术生成

6e3eff95e1236a2d3a4e690bbc70a301.png

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 表示常量,并且 letconst 都是块级作用域,且在当前作用域有效不能重复声明。

1.1 let 命令

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

{

   let a = 1;

   let b = 2;

}

并且 let 有以下特点:

  • 不存在变量提升:
    在ES6之前,我们 var 声明一个变量一个函数,都会伴随着变量提升的问题,导致实际开发过程经常出现一些逻辑上的疑惑,按照一般思维习惯,变量都是需要先声明后使用。

// var

console.log(v1); // undefined

var v1 = 2;

// 由于变量提升 代码实际如下

var v1;

console.log(v1)

v1 = 2;

// let

console.log(v2); // ReferenceError

let v2 = 2;

  • 不允许重复声明:let 和 const 在相同作用域下,都不能重复声明同一变量,并且不能在函数内重新声明参数

// 1. 不能重复声明同一变量

// 报错

function f1 (){

   let a = 1;

   var a = 2;

}

// 报错

function f2 (){

   let a = 1;

   let a = 2;

}

// 2. 不能在函数内重新声明参数

// 报错

function f3 (a1){

   let a1;

}

// 不报错

function f4 (a2){

   {

       let a2

   }

}

1.2 const 命令

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

const PI = 3.1415926;

console.log(PI);  // 3.1415926

注意点

  • const 声明后,无法修改值;

const PI = 3.1415926;

PI = 3;

// TypeError: Assignment to constant variable.

  • const 声明时,必须赋值;

const a ;

// SyntaxError: Missing initializer in const declaration.

  • const 声明的常量, let 不能重复声明;

const PI = 3.1415926;

let PI = 0;  

// Uncaught SyntaxError: Identifier 'PI' has already been declared

2 变量的解构赋值

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

2.1 数组

基础用法

// ES6 之前

let a = 1;

let b = 2;

// ES6 之后

let [a, b] = [1, 2];

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

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

console.log(a, b, c); // 1, 2, 3

let [ , , c] = [1, 2, 3];

console.log(c);       // 3

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

console.log(a,c);     // 1, 3

let [a, ...b] = [1, 2, 3];

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

let [a, b, ..c.] = [1];

console.log(a, b, c); // 1, undefined, []

注意点

  • 如果解构不成功,变量的值就等于 undefined

let [a] = [];     // a => undefined

let [a, b] = [1]; // a => 1 , b => undefined

  • 当左边模式多于右边,也可以解构成功。

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

console.log(a, b); // 1, 2

  • 两边模式不同,报错。

let [a] = 1;

let [a] = false;

let [a] = NaN;

let [a] = undefined;

let [a] = null;

let [a] = {};

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

let [a = 1] = [];      // a => 1

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

特殊情况:

let [a = 1] = [undefined]; // a => 1

let [a = 1] = [null];      // a => null

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

2.2 对象的解构赋值

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

基础用法

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

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

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

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

注意点

  • 变量名属性名不一致,则需要修改名称。

let {a:b} = {a:1, c:2};

// error: a is not defined

// b => 1

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

  • 对象解构也支持嵌套解构

let obj = {

   a:[ 1, { b: 2}]

};

let {a, a: [c, {b}]} = obj;

// a=>[1, {b: 2}], b => 2, c => 1

指定解构的默认值

let {a=1} = {};        // a => 1

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

let {a:b=3} = {};      // b => 3

let {a:b=3} = {a:4};   // b = >4

// a是模式,b是变量 牢记

let {a=1} = {a:undefined};  // a => 1

let {a=1} = {a:null};   // a => null

// 因为null与undefined不严格相等,所以赋值有效

// 导致默认值1不会生效。

2.3 字符串的解构赋值

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

const [a, b, c, d, e] = 'hello';

a // "h"

b // "e"

c // "l"

d // "l"

e // "o"

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

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

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

// 数值和布尔值的包装对象都有toString属性

let {toString: s} = 123;

s === Number.prototype.toString // true

let {toString: s} = true;

s === Boolean.prototype.toString // true

let { prop: x } = undefined; // TypeError

let { prop: y } = null;      // TypeError

2.5 函数参数的解构赋值

基础用法

function fun ([a, b]){

   return a + b;

}

fun ([1, 2]); // 3

指定默认值的解构:

function fun ({a=0, b=0} = {}){

   return [a, b];

}

fun ({a:1, b:2}); // [1, 2]

fun ({a:1});      // [1, 0]

fun ({});         // [0, 0]

fun ();           // [0, 0]

function fun ({a, b} = {a:0, b:0}){

   return [a, b];

}

fun ({a:1, b:2}); // [1, 2]

fun ({a:1});      // [1, undefined]

fun ({});         // [undefined, undefined]

fun ();           // [0, 0]

2.6 应用

  • 交换变量的值:

let a = 1,b = 2;

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

  • 函数返回多个值:

// 返回一个数组

function f (){

   return [1, 2, 3];

}

let [a, b, c] = f(); // a=>1, b=>2, c=>3

// 返回一个对象

function f (){

   return {a:1, b:2};

}

let {a, b} = f();    // a=>1, b=>2

  • 快速对应参数: 快速的将一组参数与变量名对应。

function f([a, b, c]) {...}

f([1, 2, 3]);

function f({a, b, c}) {...}

f({b:2, c:3, a:1});

  • 提取JSON数据

let json = {

   name : 'leo',

   age: 18

}

let {name, age} = json;

console.log(name,age); // leo, 18

  • 遍历Map结构:

const m = new Map();

m.set('a', 1);

m.set('b', 2);

for (let [k, v] of m){

   console.log(k + ' : ' + v);

}

// 获取键名

for (let [k] of m){...}

// 获取键值

for (let [,k] of m){...}

  • 输入模块的指定方法: 用于按需加载模块中需要用到的方法。

const {log, sin, cos} = require('math');

3 字符串的拓展

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

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

  • includes():返回布尔值,表示是否找到参数字符串

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

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

let a = 'hello leo';

a.startsWith('leo');   // false

a.endsWith('o');       // true

a.includes('lo');      // true

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

let a = 'hello leo';

a.startsWith('leo',1);   // false

a.endsWith('o',5);       // true

a.includes('lo',6);      // false

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

3.2 repeat()

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

'ab'.repeat(3);        // 'ababab'

'ab'.repeat(0);        // ''

特殊用法:

  • 参数为 小数,则取整

'ab'.repeat(2.3);      // 'abab'

  • 参数为 负数或 Infinity,则报错

'ab'.repeat(-1);       // RangeError

'ab'.repeat(Infinity); // RangeError

  • 参数为 0到-1的小数或 NaN,则取0

'ab'.repeat(-0.5);     // ''

'ab'.repeat(NaN);      // ''

  • 参数为 字符串,则转成 数字

'ab'.repeat('ab');     // ''

'ab'.repeat('3');      // 'ababab'

3.3 padStart(),padEnd()

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

'x'.padStart(5, 'ab');   // 'ababx'

'x'.padEnd(5, 'ab');     // 'xabab'

特殊用法:

  • 原字符串长度,大于或等于指定最小长度,则返回原字符串。

'xyzabc'.padStart(5, 'ab'); // 'xyzabc'

  • 用来补全的字符串长度和原字符串长度之和,超过指定最小长度,则截去超出部分的补全字符串。

'ab'.padStart(5,'012345'); // "012ab"

  • 省略第二个参数,则用 空格补全。

'x'.padStart(4);           // '    x'

'x'.padEnd(4);             // 'x    '

3.4 模版字符串

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

let a = 'abc' +

   'def' +

   'ghi';

ES6之后:

let a = `

   abc

   def

   ghi

`

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

// ES6之前

let a = 'abc' + v1 + 'def';

// ES6之后

let a = `abc${v1}def`

4 正则的拓展

4.1 介绍

在ES5中有两种情况。

  • 参数是字符串,则第二个参数为正则表达式的修饰符。

let a = new RegExp('abc', 'i');

// 等价于

let a = /abx/i;

  • 参数是正则表达式,返回一个原表达式的拷贝,且不能有第二个参数,否则报错。

let a = new RegExp(/abc/i);

//等价于

let a = /abx/i;

let a = new RegExp(/abc/, 'i');

//  Uncaught TypeError

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

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

4.2 字符串的正则方法

常用的四种方法: match()replace()search()split()

4.3 u修饰符

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

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

/^\uD83D/.test('\uD83D\uDC2A');  // true

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

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

  • (1)点字符 点字符( .)在正则中表示除了换行符以外的任意单个字符。对于码点大于 0xFFFF的Unicode字符,点字符不能识别,必须加上 u修饰符。

var a = "?";

/^.$/.test(a);  // false

/^.$/u.test(a); // true

  • (2)Unicode字符表示法 使用ES6新增的大括号表示Unicode字符时,必须在表达式添加 u修饰符,才能识别大括号。

/\u{61}/.test('a');      // false

/\u{61}/u.test('a');     // true

/\u{20BB7}/u.test('?'); // true

  • (3)量词 使用 u修饰符后,所有量词都会正确识别码点大于 0xFFFF的 Unicode 字符。

/a{2}/.test('aa');    // true

/a{2}/u.test('aa');   // true

/?{2}/.test('??');  // false

/?{2}/u.test('??'); // true

  • (4)i修饰符 不加 u修饰符,就无法识别非规范的 K字符。

/[a-z]/i.test('\u212A') // false

/[a-z]/iu.test('\u212A') // true

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

const a = /hello/;

const b = /hello/u;

a.unicode // false

b.unicode // true

4.4 y修饰符

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

var s = 'aaa_aa_a';

var r1 = /a+/g;

var r2 = /a+/y;

r1.exec(s) // ["aaa"]

r2.exec(s) // ["aaa"]

r1.exec(s) // ["aa"]  剩余 '_aa_a'

r2.exec(s) // null

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

const a = /a/y;

a.lastIndex = 2;  // 从2号位置开始匹配

a.exec('wahaha'); // null

a.lastIndex = 3;  // 从3号位置开始匹配

let c = a.exec('wahaha');

c.index;          // 3

a.lastIndex;      // 4

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

'a1a2a3'.match(/a\d/y);  // ["a1"]

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

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

const a = /hello\d/y;

a.sticky;     // true

4.5 flags属性

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

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

8b020ec43007225205e5f5eaf90b2e09.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值