ES 6

  • 简介
  • let 声明变量
    • 变量不提升
    • 暂时性死区 TDZ
    • const 静态变量 (常量*)
      • 实质
      • 引申
  • 对象冻结
  • 解构赋值
    • 起步
    • ...arr 展开运算符
    • ...[] 数组拓展运算符
      • 传参
      • 找最大值
      • 与三目运算符结合
      • 模拟深复制
      • 模拟 concat
    • 结构解析
      • 详细步骤
  • 惰性求值
  • 模板字符串

简介

  • 2015年6月17日,ECMAScript 6发布正式版本,即ECMAScript 2015。
  • ES6 是继 ES5 之后的一次主要改进,ES6 增添了许多必要的特性,例如:模块和类,以及一些实用特性,例如Maps、Sets、Promises、生成器(Generators)等。
  • 尽管 ES6 做了大量的更新,但是它依旧完全向后兼容以前的版本,标准化委员会决定避免由不兼容版本语言导致的“web体验破碎”。结果是,所有老代码都可以正常运行,整个过渡也显得更为平滑,但随之而来的问题是,开发者们抱怨了多年的老问题依然存在。

let 声明变量

let 是新的变量声明

  • 如果声明的位置是在代码块中,那么变量只能在代码块里有用
  • 代码块,类似于 iffor 循环 等等。
 if(true){let a = 1;}console.log(a);//Uncaught ReferenceError: a is not defined

变量不提升

不像 var ,这个没有变量提升
所以,必须先声明,再使用

 console.log(b);let b;//Uncaught ReferenceError: Cannot access 'b' before initialization

暂时性死区 TDZ

全称:temporal dead zone

声明变量之前不允许使用

 if(true){/*TDZ start*/typeof temp;let temp;/* TDZ end*/console.log(temp);}//Uncaught ReferenceError: Cannot access 'temp' before initialization
  • 注意 TDZ 的区域,从代码块开始,到定义完变量之后,这一小段是 TDZ,
  • 引申:在 es6 中 typeof 不是绝对安全了
 //多看代码,加深理解var c = 1;function test() {console.log(c);if(true){//这个c只是在if中有效let c = 10;}}test()//1
 //跟上一个对比var c = 1;function test() {console.log(c);if(true){//这里有变量提升var c = 10;}}test()//undefined
 //这个要注意一下var a = 1;function test() {console.log(a);//条件是falseif(false){/*先进去if中探索一下是否有 var 声明,然后再去判断语句*//*这个if在刚开始还是进去的,遇到var也还会提升,只是语句在执行的时候,没有进入if*/var a = 10;}}test();//undefined
  • 这里有个情况
 let x;//这把{x}当作了代码块,解决这个问题的话,整体加圆括号{x} = {x:1}console.log(x);//Uncaught SyntaxError: Unexpected token '='
 //解决方法let x;//{x} = {x:1}({x} = {x:1});console.log(x);//1

const 静态变量 (常量*)

有如下属性

  • 不允许重复声明
  • 声明的时候赋值
  • 声明之后不允许修改
  • let 的作用域一个德行,都是代码块里有效

实质

  • const 实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动
  • 对于 简单类型 的数据(数值,字符串,布尔值),存在 中,值就保存在变量指向的那个内存地址。
  • 对于 复杂对象(主要是对象和数组),变量指向的内存地址存在 中,保存的是指向,指向的数据怎么变,它管不到

引申

  • 栈:大小固定,自动分配,能由系统自动释放掉
  • 堆:可变大小,不能自动释放掉

对象冻结

用到了 Object.freeze(); 方法

 const obj = Object.freeze({name:"张三"});
  • 建议前面写上 const,因为如果你这样,之后也能改变指向,如果你用了 const,就改变不了了
 //用var,声明不变的量,也不安全var obj = Object.freeze({name:"张三"});obj = {};console.log(obj);//{}
 //使用const声明const obj = Object.freeze({name:"张三"});obj = {};console.log(obj);//Uncaught TypeError: Assignment to constant variable.
  • 冻结之后,如果想要修改内容的话,是不会报错的,但是并不能修改内容(以为对象冻结住了)
  • 如果想要修改内容的话,就需要解冻。
 const obj = Object.freeze({name:"张三"});obj["name"] = "小子";console.log(obj);//{name: "张三"}


解构赋值

起步

可迭代的数据都可以解构赋值(数字就不行了)

  • 简单的解构赋值如下
 let [a,b,c] = [1,2,3];console.log(a);console.log(b);console.log(c);//1//2//3
  • 快速互换两个值:比方说
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log("a,b", a, b);   // a,b 2 1
  • 也可以用来当作函数的实参、形参,而且 解构赋值 有个好处,可以传 ""undefinednullfalse 这些东西。
 //例子1:普通给默认值的方法//如果你传的值是undefined等,他是走默认值0的,而我们希望走的是undefinedfunction test_bad(val) {val = val || 0;console.log(val);}test_bad("");test_bad(undefined);test_bad(null);test_bad(false);//0//0//0//0
 //例子1的对比,优化//如果你传来的不是严格的 undefined,那么就会走默认值function test_good([a,b,c = 0,d = 4,e]) {console.log(a);console.log(b);console.log(c);console.log(d);console.log(e);}test_good([false,null,"",undefined,"undefined"]);//false//null////4//undefined
  • 如果想要让obj2 拿到obj 的内容,修改obj2还不影响obj,那么可以解构obj (解构之后就变成了个新的对象),然后在赋值给obj2
 let obj = {a: 1,b: 2,
};
// let obj2 = {...obj}
let obj2 = obj;
// 如果想要让obj2 拿到obj 的内容,修改obj2还不影响obj,那么可以解构obj,然后在赋值给obj2
obj2.a = 10;
console.log(obj);

…arr 展开运算符

先来一个例子,慢慢理解一下

  • ...arr 一定要保证是在后面,因为它只能解析从某个地方到 数组尾部
 //不能这样:let[...arr,a] = ["ar",2,3,4];let[a,...arr] = ["ar",2,3,4];console.log(a);console.log(arr);//ar//(3) [2, 3, 4]
  • 如果没有值得话,就会生成一个空数组
 let[a,b,...arr] = ["ar"];console.log(arr)//Array(0)
  • 也可以遍历字符串
  • 可以设置默认值,如果严格等于undefined,那么就走默认值(底层是 ===
 //严格等于 undefined,走默认的值let [a = 100,b = "poi"] = [undefined];console.log(a);console.log(b);//100//poi//不严格等于 undefined ,走赋值let [a = 100,b = "poi"] = ["undefined"];console.log(a);console.log(b);//undefined//poi
 //再来一个引申var a = undefined;var b = "undefined";//0 == 1console.log(a == b);//两等都不行了,三等就更没戏了console.log(a === b);//false//false
  • 还能承接传来的参数,这个叫做 rest
 function test(...arr) {console.log(arr);}test(1,2,3,4)//(4) [1, 2, 3, 4]

…[] 数组拓展运算符

  • 这个就相当于 rest 的逆运算,一个是聚合,一个是拆散,...[1,2,3] 会被拆成 1 2 3
 var f1 = (a,b,c,d) => {console.log(a);console.log(b);console.log(c);console.log(d);//1//2//3//4};f1(1,...[2,3,4]);
  • 这个功能就很强大了,可以跟选择器结合使用
<body><div>1</div><div>2</div><div>3</div>
</body>
<script>console.log(...document.querySelectorAll("div"));
</script>

传参

  • 而且与 rest 不同的是,可以不用放到最后
 //1.解析的时候和rest不同的是,可以不用放到最后function f1(a,b,c,d,e) {console.log(a,b,c,d,e);}//[2,3,4]放到了参数们的中间,而rest必须放到后面才能正常使用arr1 = [1,...[2,3,4],5];//es5传参f1.apply(null,arr1);//1,2,3,4,5//es6f1(...arr1);//1,2,3,4,5

找最大值

 var arr1_1 = [10,2,4654,789,56,6,131,32,];//es5的写法console.log(Math.max.apply(null,arr1_1));//4654//es6的写法console.log(Math.max(...arr1_1));//4654

与三目运算符结合

 var x = 2;var arr2 = [...(x == 1?[1,2,3]:[4,5,6]),"x"];console.log(arr2);//(4) [4, 5, 6, "x"]

空的话,不会报错,控制台里就没有它的打印信息

 var arr3 = [];console.log(...arr3);

模拟深复制

 const a3 = [3,4,5];//2.模拟深复制const a4 = [...a3];console.log(a4);//(3) [3, 4, 5]

模拟 concat

 var arr3_1 = [1,2,3];var arr3_2 = [4,5,6];console.log(arr3_1.concat(arr3_2));//(6) [1, 2, 3, 4, 5, 6]console.log([...arr3_1,...arr3_2]);//(6) [1, 2, 3, 4, 5, 6]

结构解析

  • 对象解析当中根据 key 来解析
  • let {匹配模式:变量}
 let {c,a}  = {b:"6666",a:"555"};console.log(a);console.log(c);//555//undefined
  • 数组相当于一个特殊的对象,可以用 下标 当作 key 值去解析
 /*数组的结构解析*/var arr = ["dsada","ewq",'zxcvc',16,18,"135"];let {1:fir,[arr.length-1]:last} =  arr;console.log(fir);console.log(last);//ewq//135

详细步骤

 //目的:我想解析shuaivar obj = {foo:['ufo',{sss:"shuai"}]};/*结构解析*//*第一步:等号左右类型要一样*/let {} = obj;/*第二步:添加匹配模式foo*/let {foo} = obj;/*第三步,这个时候b就代表了对象,数组的话就不需要匹配模式,随便一个符号占着茅坑找位置就行*/let {foo:[a,b]} = obj/*第四步:把b变成括号,然后再用匹配模式sss,来进入对象中*/let {foo:[a,{sss}]} = obj;/*第五步:你可以给sss赋值变量l,然后输出l就可以了*/let {foo:[a,{sss:l}]} = obj;console.log(l);
 //觉得你行了?来试试这个,少年,解析girlvar sister = [{age:[18,{sex:"girl"}]}];
  • 加深理解接着玩 ,console 也能解析
 /*console是个对象,他有log方法,我把log方法解析出来*/let {log} = console;log("111");//111
 /*对象 = 对象,把 math 对象中的属性承接出来,放到 PI 中,因为 PI 是属性值,所以打印就好* 如果是函数体的话就给参数调用*/const {PI} = Math;console.log(PI);3.141592653589793
 //let {匹配模式:变量}//默认是let {foo:foo} = {foo:"cszsdad"};let {foo:fooValue} = {foo:"cszsdad"};console.log(fooValue);//cszsdad
  • 结构解析也能分析继承的
 Person.prototype.name = "lsl";function Person() {}var p = new Person();let {name:n} = p;console.log(n);//lsl
  • 理解了之后自己玩了一个比较瑟琴的
 //给你们答案,不唯一var sister = [{age:[18,{sex:"girl"}]}];   let [{age:[a,{sex:x}]}] = sister;console.log(x);

惰性求值

 function f() {throw new Error("this is error");}/*惰性求值*//*如果有值得话,除了undefined,就一直不走默认的*/let [x = f()] = [1];console.log(x);//1
 function f() {throw new Error("this is error");}//这样就走了默认的let [x = f()] = [undefined];/*let [x = f()] = [1];*/console.log(x);//Uncaught Error: this is error

模板字符串

  • 优点:不需要我们拼接变量(原生的不是得用 + 来拼接成很长的句子嘛)
  • 符号:`` (TAB上面的那个~)
  • 想在模板字符串中插入变量的话用 ${}
  • 还是函数调用的另一种形式
 //函数调用,括号变成``也可以alert `4`;
 //模板字符串的简单使用const obj = {name:18,age:"xiaopang",habit:"sing",};var str = `my name is ${obj.name} ,age is ${a}`;console.log(str);//my name is 18 ,age is xiaopang
  • 如果你非要在模板字符串中打出 `` 这个符号,那么可以用转义字符 \
 //转移字符var str1 = `\`\``;console.log(str1);//``
  • 这个还可以插标签,可以进行变量的运算,注意写法、还可以插入方法,而且还会 解析换行,你怎样写,就会在页面上解析成相应的样子,包括换行,空格。
 //综合应用var x = 5;var arr = [1,2,3,4,5];//插入标签,运算,arr.reverse()方法,对象引用$("#test").html(`<ul><li style="font-size: ${x + 40}px;">1</li><li>22\`\`</li><li>${arr.reverse()}</li><li>${obj.name + x}</li></ul>`)

  • 如果当作实参的话,字符串里穿插变量,那么形参中可以接到如下的东西
 var xx = 1;var yy = 2;var zz = 3;function show (a,b,c,d,e) {/*这个a是实参中所有字符串的字段,并放到数组中*/console.log(a);console.log(b);console.log(c);console.log(d);console.log(e);}show `this  ${xx}  is  ${yy} a ${zz}  iu`;//(4) ["this  ", "  is  ", " a ", "  iu", raw: Array(4)]//1//2//3//undefinedfunction show1 (a,...arr) {console.log(a);console.log(arr);}/*如果变量放到了第一个,前面没有字符串,那么a[0]会被解析成空字符串*/show1 `${xx}  is  ${yy} a ${zz} this`;//["", "  is  ", " a ", " this", raw: Array(4)]//(3) [1, 2, 3]//解释:/*最前面的和最后面的变量,在这里是${xx}和${zz}*///最前面的变量${xx},看它的前面,有字符串那么就拿,如果没有就会拿空//最后面的变量${zz},看他的后面,有字符串那么就拿,如果没有就会拿空

【前端17_JS】ES 6:Let 、Const、对象冻结、解构赋值、暂时性死区 TDZ、惰性求值、模板字符串相关推荐

  1. Vue学习笔记(三)Vue2三种slot插槽的概念与运用 | ES6 对象的解构赋值 | 基于Vue2使用axios发送请求实现GitHub案例 | 浏览器跨域问题与解决

    文章目录 一.参考资料 二.运行环境 三.Vue2插槽 3.1 默认插槽 3.2 具名插槽 3.3 作用域插槽 ES6解构赋值概念 & 作用域插槽的解构赋值 3.4 动态插槽名 四.GitHu ...

  2. 【ES6】let命令、const命令、解构赋值

    let命令 ES6 新增了let命令,用来声明变量.它的用法类似于var,但是也存在新的特性. let所声明的变量,只在let命令所在的代码块内有效,避免全局污染.(适用于for循环) {let a ...

  3. ES6 对象的解构赋值

    对象的解构赋值 解构不仅可以用于数组,还可以用于对象. var { foo, bar } = { foo: "aaa", bar: "bbb" }; foo / ...

  4. 【ES6学习】对象的解构赋值

    解构不仅可以用于数组,还可以用于对象. let { foo , bar } = { foo :"aaa ", bar :"bbb " } ; too // &q ...

  5. js 对象的解构赋值

    2023.1.29今天我学习了对象的解构赋值. 解构不仅可以用于数组,还可以用于对象. let {foo,bar} = {foo : "aaa",bar : "bbb&q ...

  6. ECMAScript6学习笔记 ——let、const、变量解构赋值

    let 不存在变量提升 通过let声明的变量仅在块级作用域内有效 不允许在同一个作用域内重复声明一个变量 防止值公用 var oUl = document.querySelectorAll('ul&g ...

  7. java对象赋值给数组_带你深入的理解数组和对象的解构赋值。

    es6提供了一个非常好的特性,即变量的解构赋值.从而我们可以方便的从数组和对象中提取数据并将它们赋值给变量.这是非常必要的.先来看在这个新特性发布之前我们是如何从数组中提取数据的.如下: let nu ...

  8. 前端学习必备之ES6解构赋值的常见用法

    1.解构赋值可以轻松获取对象或者数组中的数据 var jsonData = {data: "111",data2: ["test","test2&qu ...

  9. 【ES6】阮一峰ES6学习(一) let、const、解构赋值

    let 和 const 命令 1. let 概念:块级作用域. 不存在变量提升:在声明变量前使用该变量,会报错. 暂时性死区:形成了封闭作用域,在代码块内,使用let声明变量之前,该变量都是不可用的. ...

最新文章

  1. SSIS--FOR循环容器
  2. Google X的机器人开始打工!进咖啡馆擦桌子:擦的很慢,但我们一直在做
  3. ASP.NET安全问题--ASP.NET中的授权问题(前篇)
  4. 深入理解java中的ArrayList和LinkedList
  5. android studio下的NDK开发详解
  6. 委托学习总结(一)浅谈对C#委托理解
  7. 根据BAPI_PO_CREATE1创建采购订单
  8. Google AdSense中文官方博客今天公布了AdSense内容广告与AdSense搜索广告的收入分成比例...
  9. 13 个开源备份解决方案
  10. NSTimer实现读秒、倒计时等周期性操作
  11. 一千五百个优雅的中国女孩的名字
  12. 潮流仿真分析matlab,基于MATLAB的电力系统潮流仿真与研究
  13. ArcGIS 地表TIN面数据的符号化
  14. 论文笔记——分布式深度学习框架下基于性能感知的DBS—SGD算法
  15. matlab二次求导函数,原来可以这样求导函数,再复杂的函数求导不再话下!
  16. NoteExpress免费版只7个引文样式#NoteExpress免费版新增引文样式
  17. 序列号 java_JAVA序列号的serialVersionUID
  18. 认识并行、并发、多线程
  19. 前端-超链接,相对路径
  20. iOS KeyChain使用

热门文章

  1. 硬盘加密数据怎么恢复?BitLocker加密文件可恢复吗?BitLocker加密数据怎么恢复?
  2. Single Yuanz(单一原则)
  3. 浅谈阿里云混合云新一代运维平台演进与实践
  4. 微信公众平台开发入门
  5. codeforces 722C Destroying Array
  6. 231个web前端的javascript特效分享(仅供本人学习,非教程类型)
  7. Labplus:Scratch创作工具的替代与进步
  8. 浮点数转换为大写货币金额
  9. 系统安装 使用VMware15安装Win7系统
  10. 研究显示情商高的人比智商高的可怕多了