《es6标准入门》学习笔记-第二章 let和const命令
来源:互联网 发布:淘宝格子铺怎么入驻 编辑:程序博客网 时间:2024/04/30 21:18
以下内容使用的书籍为《es6标准入门-第2版》,阮一峰著,如有需要请购买正版
本文仅为个人读书笔记,如有不详之处请查阅原文
es5提供了var 和function两种变量声明方法,在es6中提供了额外的4中声明方法,分别为let,const,import,class,本章将讲述let和const两种
- let
- 基本用法
- 不存在变量提升
- 暂时性死区TDZ
- 不允许重复声明
- 基本用法
- 块级作用域
- 为什么要有块级作用域
- ES6的块级作用域
- const
- 基本用法
- 对象和数组
- 跨模块常量
- 全局对象的属性
- let
let
基本用法
let仅在所在的代码块内有效(即被{}包裹的区间内)
{ let a=1; var b=1;}a //ReferenceError: a is not definedb //1
for循环的计数器就很适合let
var a=[]; for(let i=0;i<10;i++){ a[i]=function(){ console.log(i) } } a[6](); //6
let仅在本轮循环中有效,相当于每次循环都是一个新的变量
不存在变量提升
typeof x;let x=1;
这将抛出一个ReferenceError异常,因为let不存在变量提升,所以变量一定要在声明之后使用。
暂时性死区(TDZ)
只要区块作用域中存在let命令,那么它声明的变量就跟这个区块绑定了,不再受外部影响
var tmp="test it";if(true){ tmp="abc"; //ReferenceError let tmp;}
如果区块中存在let和const命令,则这个区块对这些声明变量从一开始就形成封闭作用域,只要在声明之前使用这个变量就会报错。使用let命令声明变量之前,该变量都不可以使用,这在语法上被称为“暂时性死区”(temporal dead zone,简称TDZ),所有在let生命变量之前使用该变量的区域都称为该变量的死区
有些死区比较隐蔽
function bar(x=y,y=1){ return [x,y]}bar();
这里会抛出ReferenceError,而不是返回[undefind,1]
不允许重复声明
let不允许在相同作用域内重复声明
function bar(){ let a=1; let a=10;}//Identifier 'a' has already been declared
同样,不能在函数内部重复声明参数
function bar(a){ let a=1; // Identifier 'a' has already been declared}function bar2(a){ { let a=1; // 不会报错 }}
块级作用域
为什么要有块级作用域
避免变量提升导致的内部变量覆盖外部变量
var tmp=new Date();function f(){ console.log(tmp); if(true){ var tmp=12 }}f()//undefined
避免计数器的循环变量泄露为全局变量
for(var i=0;i<10;i++){}console.log(i);//10
ES6的块级作用域
let为ES6增加了块级作用域
ES6允许块级作用域任意嵌套
{{{{{{{let insane="hello word"}}}}}}}
外层作用域无法读取内层作用域的变量
{{{{{{ {let insane="hello word"} console.log(insane)//insane is not defined }}}}}}
内层作用域可以定义外层作用域的同名变量
{{{{{{ let insane="outside" { let insane="inside" console.log(insane)//inside } console.log(insane)//outside }}}}}}
函数本身的作用域在其所在的区块级作用域之内
function f(){ console.log('I am outside')}(function(){ if(false){ function f(){ console.log('I am inside') } } f();})();//es5显示inside,es6显示outside
const
基本用法
const用来声明常量,一旦声明,其值就不能改变
const Pi=3.1415926console.log(Pi)//3.1415926Pi=3;//TypeError: Assignment to constant variable
const一旦声明就必须赋值
const a;//SyntaxError: Missing initializer in const declaration
const的作用域和let一样,只在块级作用域有效
const不存在变量提升,同样存在死区
const也不能重复声明
以上示例参照let
对象和数组
const可以声明一个数组或者对象类型的变量,并且其值是可写的,但是不能重新赋值
const a=[];a.push(1);console.log(a);//[1]a=[];//TypeError: Assignment to constant variable.
const a={}a.b=3console.log(a);//{b:3}a={}//TypeError: Assignment to constant variable.
var b={c:1}const a=ba.c=2;console.log(a);//{c:2}console.log(b);//{c:2}a={}//TypeError: Assignment to constant variable.
如果希望a的所有属性都不可写,可以使用Object的freeze方法,将对象冻结
const foo=Object.freeze({});foo.prop=1;console.log(foo);//{}
上面的代码将foo指向一个冻结对象,所以新增属性不起作用
除了对象本身冻结,对象的属性也应该冻结,下面是一个将对象彻底冻结的函数 比部分用了其它的es6内容,可在看完后面的部分后,再回来看
var constantize=(obj)=>{ Object.freeze(obj); Object.keys(obj).forEach((key,value)=>{ if( typeof obj[key] === 'object'){ constantize(obj[key]); } }) }
跨模块常量
const只对当前块级作用域有效,以下可以设置跨模块常量
//constants.jsexport const A=1;export const B=2;export const C=3;
//test1.jsimport * as constants from './constants';console.log(constants.A)//1console.log(constants.B)//2
//test2.jsimport {A,B} as constants from './constants';console.log(A//1console.log(B)//2
全局对象的属性
浏览器中的全局对象为window,node中的全局对象为global
在ES5中,全局对象的属性和全局变量是等价的
ES6中var和function声明的全局变量依旧是全局对象的属性,而let const class声明的全局变量不属于全局对象的属性
var a=1;//如果是node则下面为global.aconsole.log(window.a)//1let b=1;console.log(window.b)//undefinedwindow.b=2;//Identifier 'b' has already been declaredconsole.log(b)//1console.log(window.b)//2
- 《es6标准入门》学习笔记-第二章 let和const命令
- 《ES6标准入门》:let 和 const 命令
- ES6学习笔记: let 和 const 命令
- ES6学习笔记let和const命令
- ES6学习笔记(一)--let和const命令
- ES6 学习笔记之一《let和const命令》
- ES6 笔记: 2.let和const命令
- ES6学习--let和const命令
- es6学习-let和const命令
- ES6学习笔记之《let 和 const》
- es6学习笔记(let和const)
- es6学习笔记01---let和const
- 1、let和const -ES6学习笔记
- 学习笔记:ES6之let和const
- ES6学习2章:let和const命令
- es6 let 和 const 命令
- ES6 let和const命令
- ES6学习笔记 (let、const)
- LeetCode Basic Calculator II(加减乘除计算器)
- Redhat 7.1使用CentOS 7 的Yum网络源
- 图片拍照上传和相册选取
- jni下添加打印信息
- LINUX C 语言--进程管理(一)
- 《es6标准入门》学习笔记-第二章 let和const命令
- 由多线程内存溢出产生的实战分析
- JAVA通过WebService上传文件
- CocoaPods报错:The dependency '三方框架Name' is not used in any concrete target
- JAVA总结系列之Map
- 《es6标准入门》学习笔记-第三章 变量的解构赋值
- C++11读书笔记—0(迟到的C++11)
- html基本模块
- StringBuilder&& StringBuffer