ES6标准-【一】【学习ES6看这一篇就够了!!】

news2024/11/25 18:43:36

目录

顶层对象的属性

ES5中的顶层对象

ES6中的顶层对象

数组的解构赋值

默认值

对象的解构赋值

默认值

注意点:

字符串的解构赋值

数值和布尔值的解构赋值

函数参数的解构赋值

ES6中的圆括号问题

不能使用圆括号的情况

变量声明语句

函数参数

赋值语句的模式

可以使用圆括号的情况

变量解构赋值的用途【重要】

1.交换变量的值

2.从函数返回多个值

3.函数参数的定义

4.提取JSON数据

5.遍历MAP结构

顶层对象的属性

ES5中的顶层对象

顶层对象,在浏览器环境指的是window对象,ES5中顶层对象的属性与全局变量是等价的

window.a = 1;
console.log(a);
a = 2;
console.log(window.a)

 

对顶层对象的属性赋值与全局变量的赋值,是同一件事

ES6中的顶层对象

在ES6中:

“var”和“function”命令声明的全局变量,依旧是顶层变量的属性;

“let”命令、“const”命令、“class”命令声明的全局变量,不属于顶层的对象属性

var a = 1;
window.a // 1
let b = 1;
window.b // undefined

数组的解构赋值

ES6允许按照一定模式,从数组和对象中提取值,并对变量赋值,这被称为“解构

以前,为变量赋值,只能直接指定值

let a = 1;
let b = 2;
let c = 3;

ES6中允许写成下面这个样子

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

上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

let [foo,[[bar],baz]] = [1,[[2],3]]
foo // 1
bar // 2
baz // 3

let [,,third] = ["foo","bar","baz"]
third // "baz"

let [x,,y] = [1,2,3]
x // 1
y // 3

let [head,...tail] = [1,2,3,4]
head // 1
tail // [2,3,4]

//注意区别...tail 与 tail的区别
let [head,tail] = [1,2,3,4]
head // 1
tail // 2

let [x,y,...z] = ['a']
x // 'a'
y // undefined
z // []
// ...变量名 模式匹配一个数组

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

let [foo] = [];

let [a,b] = [1];

let [...c] = [];

foo // undefined

a // 1

b // undefined

c // []

不完全解构,只匹配一部分等号右边的数组:

let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

如果等号的右边不是数组(不是可遍历的结构),那么将会报错:

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

上面的语句都会报错,因为等号右边的值不是一个“可遍历结构” 

默认值

解构赋值允许给变量手动指定默认值

具有默认值的变量如果右侧等式对应位置存在一个值,则默认值会被替换

let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

ES6内部使用严格相等运算符( === ),判断一个位置是否有值。所以,只有当一个数组成员严格等于“undefined”时,默认值才会生效

let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
// null不严格等于undefined所以不会生效

默认值可以引用“一条语句内解构赋值的其他变量”(但该变量必须已经声明):

let [x = 1, y = x] = [];     // x=1; y=1
let [x = 1, y = x] = [2];    // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = [];     // ReferenceError: y is not defined

上面最后一个表达式报错,是因为y变量在后面,还没有声明,改为下面格式:

let [y=1,x=y] = [];

x // 1

y // 1

就不会报错

对象的解构赋值

解构不仅可以用于数组,还可以用于对象

解构的是对象属性值,而不是对象属性名

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

对象的属性没有次序,变量必须与属性同名,才能取到正确的值

即:“对象的解构赋值与次序无关

let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined

如果解构失败,变量的值等于undefined

let {foo} = {bar: 'baz'};
foo // undefined

对象的解构赋值,可以很方便的将对象的方法,赋值给某个变量,以后直接使用这个变量即可

// 例一
let { log, sin, cos } = Math;
// 例二
const { log } = console;
log('hello') // hello

上面将Math对象的对数、正弦、余弦三个方法,赋值到对应的变量上,使用起来就会方便很多。

例二将console.log赋值到log变量

如果变量名与属性名不一致,必须写成下面这样:

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

对象的解构赋值,实际上是下面形式的简写:

let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };

即,对象的解构赋值是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined

上面代码中,foo是匹配的模式,baz才是变量,真正被赋值的是变量baz,而不是模式foo

解构也可以用于嵌套解构的对象:

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};
let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"

一个嵌套赋值的例子:

let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
obj // {prop:123}
arr // [true]

如果结构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错:

// 报错
let {foo: {bar}} = {baz: 'baz'};

foo是一个子对象,该子对象的bar属性解构时会报错,原因是foo等于“undefined

对象的解构赋值可以取到继承的属性:

const obj1 = {};
const obj2 = { foo: 'bar' };
Object.setPrototypeOf(obj1, obj2);
const { foo } = obj1;
foo // "bar"

对象obj1的原型对象是obj2foo属性不是obj1自身的属性,而是继承自obj2的属性。

解构赋值可以取到这个属性

默认值

对象的结构也可以指定默认值

var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var {x: y = 3} = {};
y // 3
var {x: y = 3} = {x: 5};
y // 5
var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"

默认值生效的条件是,对象的属性值严格等于“undefined

var {x = 3} = {x: undefined};
x // 3
var {x = 3} = {x: null};
x // null

注意点:

如果要将一个已经声明的变量用于解构赋值,必须非常小心!!!

// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
  • 上面的代码写法会报错,因为JavaScript会将“x”理解成一个代码块,从而引发错误。只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题:
// 正确的写法
let x;
({x} = {x: 1});

解构赋值允许等号左边的模式中,不放置任何变量名。

因此可以写出非常古怪的赋值表达式,但没有什么卵用,不过可以执行

({} = [true, false]);
({} = 'abc');
({} = []);

可以对数组进行对象属性的解构

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3
  • 数组arr的0键对应的值是1[arr.length-1]就是2键,对应的值是3

字符串的解构赋值

字符串也可以解构赋值,这是因为此时,字符串被转换成了一个类似数组的对象

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个“length”属性,因此还可以对这个属性解构赋值

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

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象

let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
  • 数值布尔值的包装对象都有“toString”属性,因此变量“s”都能取到值

函数参数的解构赋值

函数的参数也可以使用解构赋值

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

上面代码中,函数add的参数表面是一个数组,但在传入参数的那一刻,数组参数就被解构为“x”和“y”变量

另一个例子:

[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [ 3, 7 ]
  • 函数参数的解构也可以使用默认值:
function move({x = 0, y = 0} = {}) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
  • 下面的写法会得到不一样的结果:
function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

ES6中的圆括号问题

ES6对于圆括号的规则是:“只要有可能导致解构的歧义,都不得使用圆括号

不能使用圆括号的情况

变量声明语句

// 全部报错
let [(a)] = [1];
let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };

函数参数

// 报错
function f([(z)]) { return z; }
// 报错
function f([z,(x)]) { return x; }

赋值语句的模式

// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];
// 报错
[({ p: a }), { x: c }] = [{}, {}];

可以使用圆括号的情况

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
  • 首先三条语句都是赋值语句,不是声明语句
  • 其次它们的圆括号都不属于模式的一部分
    • 第一行语句中,模式是取数组的第一个成员,跟圆括号无关
    • 第二行语句中,模式是p,而不是d
    • 第三行语句与第一行语句性质一致

变量解构赋值的用途【重要

1.交换变量的值

let x = 1;
let y = 2;
[x, y] = [y, x];

2.从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里面。

有了解构赋值,取出这些值就非常方便

 

// 返回一个数组
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();

3.函数参数的定义

解构赋值可以方便的将一组参数与变量名对应起来

// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

4.提取JSON数据

解构赋值对提取JSON对象中的数据,尤其有用

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]

5.遍历MAP结构

任何部署了“Iterator”接口的对象,都可以用“for...of”循环遍历,Map结构原生支持Iterator接口,配合变量的解构赋值,获取键名和键值就非常方便

const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world

如果只想获取键名或者键值可以写成下面这样:

// 获取键名
for (let [key] of map) {
  // ...
}
// 获取键值
for (let [,value] of map) {
  // ...
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2122502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JS】深拷贝与浅拷贝

深拷贝与浅拷贝 浅拷贝实现浅拷贝的方法扩展运算符 深拷贝实现深拷贝的方法递归JSON.parse(JSON.stringify()) 深拷贝和浅拷贝都是处理对象或数据的复制操作 浅拷贝 浅拷贝创建一个的对象,复制的是原对象的引用新对象与原对象共用一个相同的内存地址,因…

分布式算法-Paxos、Raft、ZAB复习

目录 1. Paxos算法 1.1 算法流程 1.2 接受者选举规则 2. Raft算法 2.1 Leader选举 2.2 安全性 3. ZAB算法 3.1 ZAB协议介绍 3.2 消息广播 3.3 崩溃恢复 3.4 数据同步 1. Paxos算法 Paxos 算法是 Leslie Lamport 在 1990 年提出的,经典且完备的分布式一致…

docker的镜像制作

镜像的加载原理 docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS UnionFS(联合文件系统): Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改…

Delphi 12.1安卓APP开发中获取硬件信息及手机号

Demo与代码已上传到CSDN下载。 这里简单说一下代码内容,完整代码请自行下载,不清楚的欢迎留言交流。 前言 演示Demo使用了我自己开发的一个控件,TLayoutPro 《Delphi D10.3 LayoutsPro 控件简介 -避免输入焦点被虚拟键盘遮挡》请查看并下载控…

第三部分:3---环境变量

目录 什么是环境变量? PATH环境变量: 临时修改环境变量PATH: HOME环境变量: 可能使用环境变量的场景: 进程和环境变量的关系: 环境变量相关操作: 代码获取环境变量: 主函数传…

百度静态资源瓦片nginx直接显示完整案例

案例地址:https://download.csdn.net/download/jinhuding/89733763 访问显示效果:(根据瓦片地址直接显示) http://172.16.39.203:8099/tiles/

(rs系列)rs4之补环境

网站:aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuLw 先讲讲rs4特征​: 1、打开控制台立刻进入无限debugger,混淆代码格式_$xx 会有两次无限debugger,直接在对应位置鼠标右键》Never pause here即可​。当然这种方法比较耗资源,也…

代码随想录算法训练营第42天|188. 买卖股票的最佳时机 IV、714. 买卖股票的最佳时机含手续费

目录 188. 买卖股票的最佳时机 IV(交易最多k次)1、题目描述2、思路3、code4、复杂度分析 714. 买卖股票的最佳时机含手续费1、题目描述2、思路3、code4、复杂度分析 309. 买卖股票的最佳时机含冷冻期1、题目描述2、思路3、code4、复杂度分析 买卖股票习题…

智能语音交互:人工智能如何改变我们的沟通方式?

在科技飞速发展的今天,人工智能(AI)已经渗透到我们生活的方方面面。其中,智能语音交互作为AI技术的一个重要分支,正以前所未有的速度改变着我们的沟通方式。从智能家居的控制到办公自动化的应用,再到日常交…

CentOs7 解决yum更新源报错:[Errno 14] HTTP Error 404 - Not Found 正在尝试其它镜像。

CentOs7 解决yum更新源报错:[Errno 14] HTTP Error 404 - Not Found 正在尝试其它镜像。 前言问题解决方法: 前言 遇到这个问题大概率是镜像源的问题可以参照这篇文章的内容试一下 镜像源问题相关解决方法 根据自己的情况对症下药,如果还不…

WPS如何删除表格下的空白页

WPS Office(12.1.0.17827) ① 鼠标右键,选择段落 ② 行距:固定值;设置值:1磅;取消勾选,确定即可~

【区块链 + 人才服务】CERX- 基于联盟链的研学资源交换网络 | FISCO BCOS应用案例

CERX 是定位于面向高校科学研究与教学的分布式研学资产交换网络,构建一个用于数据、算法模型、论文和课程的研学资源价值流转平台。该平台采用 FISCO BCOS 联盟链为核心区块链层。 CERX 基于“交叉学科”的人才培养生态,围绕“科研、课件、课程、证书”…

【C++从练气到飞升】23--内联函数、auto、范围for、nullptr

🎈个人主页:库库的里昂 ✨收录专栏:C从练气到飞升 🎉鸟欲高飞先振翅,人求上进先读书🎉 目录 ⛳️推荐 一、内联函数 1.1 定义 1.2 特性 二、auto关键字 2.1 简介 2.2 auto使用细则 2.3 不能使用aut…

ES6标准---【二】【学习ES6看这一篇就够了!!】

目录 ES6以往文章 ES6新增字符串方法: includes()、startsWith()、endsWith() repeat() padStart()、padEnd() 常见用途 为数值补全指定位数 提示字符串格式 trimStart()、trimEnd() String.raw() ES6以往文章 ES6标准-【一】【学习ES6看这一篇就够了&a…

开关电源综合测试平台自动生成报告,智能分析电源测试参数

在电源模块的检测过程中,数据的准确性和分析效率至关重要,开关电源综合测试平台的数据报告和数据分析功能为企业的电源测试带来了便利。 NSAT-8000开关电源综合测试平台是集自动化测试与数据收集分析于一体的综合测试软件,打破了传统测试系统…

【组件】WEB前端-富文本编辑器组件推荐 在线编辑器 Word

【组件】WEB前端-富文本编辑器组件推荐 在线编辑器 Word canvas-editor 基于canvas/svg的富文本编辑器 canvas-editor | rich text editor by canvas/svgrich text editor by canvas/svghttps://hufe.club/canvas-editor-docs/ canvas-editor 基于canvas/svg的富文本编辑器 开…

文案改写工具有哪些?5款智能改写工具迅速提升文案品质

在信息爆炸的时代,优秀的文案如同黄金,能瞬间抓住消费者的眼球。然而,创作出独具匠心的文案并非易事,尤其是当需要不断改写以保持文案内容新鲜感时。那么,文案改写工具有哪些是能帮助我们事半功倍呢?以下5款…

Goby 漏洞发布|(CVE-2024-45195)Apache OFBiz /viewdatafile 代码执行漏洞【已复现】

漏洞名称:Apache OFBiz /viewdatafile 代码执行漏洞(CVE-2024-45195) English Name:Apache OFBiz /viewdatafile Code Execution Vulnerability(CVE-2024-45195) CVSS core: 8.0 漏洞描述: Apache OFBiz是一个开源…

--数据库--

制作工人薪资管理系统 #include <myhead.h> #include <sqlite3.h> typedef struct {int gh;char name[20];double salary; }Worker;int do_insert(sqlite3 *ppdb) {Worker work;printf("请输入插入的工号&#xff1a;");scanf("%d",&work.…

基于Verilog HDL的FPGA设计基础

第一章 Verilog数字集成电路设计方法概述 HDL(Hardware Description Language)----硬件描述语言 EDA(Electronic Design Automation)----电子设计自动化 VLSI(Very Large Scale Integrated)----超大规模集成电路 ASIC(Application Specific Integrated Circuit)----专用集成电路…