摘要:圆括号问题可以使用圆括号的情况只有一种赋值语句的非模式部分,可以使用圆括号。正确正确正确上面三行语句都可以正确执行,因为首先它们都是赋值语句,而不是声明语句其次它们的圆括号都不属于模式的一部分。
let 和 const 命令1.let
概念:
暂时性死区(TDZ)
在作用域内,let变量已经存在;
并绑定该作用域:不受外界影响,外界也不可获取
let作用域以代码块划分,var作用域则只有全局和函数
在let声明之前,不可获取;(也就是TDZ)
在let声明之后,才可获取。
let变量不可重复声明
let不允许在相同作用域内,重复声明同一个变量。
tip:
TDZ也解释了为什么let不存在变量提升。
ES6 规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。
2.块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景,如:
内层变量可能会覆盖外层变量。
用来计数的循环变量泄露为全局变量。
ES6 的块级作用域(let实际上为 JavaScript 新增了块级作用域),作用:
外层作用域无法读取内层作用域的变量。
内层作用域可以定义外层作用域的同名变量。
使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。
根据ES6 在附录 B里的规定,在浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于var声明的变量。
3.const 命令const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
冻结对象:
const foo = Object.freeze({});
彻底冻结对象的函数:
var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach((key, i) => if ( typeof obj[key] === "object" ) { constantize( obj[key] ); } }); };
ES6 声明变量的六种方法
ES5 只有两种声明变量的方法:var命令和function命令。ES6 除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和class命令。所以,ES6 一共有 6 种声明变量的方法。
从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。
var a = 1; // 如果在 Node 的 REPL 环境,可以写成 global.a // 或者采用通用方法,写成 this.a window.a // 1 let b = 1; window.b // undefined
变量的解构赋值1.数组的解构赋值
基本用法:
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] let [x, y, ...z] = ["a"]; x // "a" y // undefined z // []
默认值
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
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
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
上面最后一个表达式之所以会报错,是因为x用y做默认值时,y还没有声明。
2.对象的解构赋值命名与键名相同则简写:
let { bar, foz } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // undefined
命名与键名不同:
let { foo: baz } = { foo: "aaa", bar: "bbb" }; baz // "aaa"
嵌套:
let obj = { p: [ "Hello", { y: "World" } ] }; let { p, p: [x, { y }] } = obj; x // "Hello" y // "World" p // ["Hello", {y: "World"}]
let obj = {}; let arr = []; ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); obj // {prop:123} arr // [true]
默认值:
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"
如果要将一个已经声明的变量用于解构赋值,必须非常小心:
// 错误的写法 let x; {x} = {x: 1}; // SyntaxError: syntax error
上面代码的写法会报错,因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
// 正确的写法 let x; ({x} = {x: 1});
由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3]; let {0 : first, [arr.length - 1] : last} = arr; first // 1 last // 33.字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = "hello"; a // "h" b // "e" c // "l" d // "l" e // "o"
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
let {length : len} = "hello"; len // 54.数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true5.函数参数的解构赋值
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]
上面代码中,函数move的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值。
注意,下面的写法会得到不一样的结果。
上面代码是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。
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]6.圆括号问题
可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。
[(b)] = [3]; // 正确 ({ p: (d) } = {}); // 正确 [(parseInt.prop)] = [3]; // 正确
上面三行语句都可以正确执行,因为首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。
第一行语句中,模式是取数组的第一个成员,跟圆括号无关;
第二行语句中,模式是p,而不是d;
第三行语句与第一行语句的性质一致。
(1)交换变量的值
(2)从函数返回多个值
(3)函数参数的定义
(4)提取 JSON 数据
(5)函数参数的默认值
(6)遍历 Map 结构
(7)输入模块的指定方法
数组的拓展1.扩展运算符(...)
用法简单,写ES6的时候留意下是否可以用之与简化代码即可,
注意点:
解构赋值的时候必须放在末尾,否则报错(Rest element must be last element)。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/93743.html
摘要:基础属性操作及注意事项待更新。。解决方案可以用视觉方案处理,比如切换显示隐藏。设置浮动时,采用在标准浏览器是支持的,在某些浏览器是不支持的。第三种判断形式条件当条件成立执行条件当条件不成立,条件成立,则执行。适用于,当某件事成立执行。 js基础--属性操作及注意事项 待更新。。 关于属性操作注意事项 1、所有相对路径都别拿来比较!!!(绝对路径可以,入img src=https://s...
摘要:会实时从上读取信息,进行重演,保持与的数据同步。如果挂掉了,会监控到,向集群发送心跳报告时会将这一消息报告上去,集群会进行选举,被选举到的所在节点的进程收到通知,这个会切换的状态为。 showImg(https://segmentfault.com/img/bVbqOJn?w=1280&h=720); 读写:客户端通过命名空间发请求,可以无感知的找到active NN,active N...
摘要:启动时会向的路径下写入文件,写入成功的则为,否则为。根据上下文以及从收集到的状态信息分配资源并调度,启动一个用来运行。负责启动,监控所在节点的资源使用情况,并通过心跳机制报告给。 showImg(https://segmentfault.com/img/bVbqOVb?w=1280&h=720); HA:RM启动时会向zk的/mrstore路径下写入lock文件,写入成功的则为acti...
阅读 998·2019-08-30 15:55
阅读 3439·2019-08-30 13:10
阅读 1267·2019-08-29 18:45
阅读 2346·2019-08-29 16:25
阅读 2106·2019-08-29 15:13
阅读 2421·2019-08-29 11:29
阅读 551·2019-08-26 17:34
阅读 1485·2019-08-26 13:57