let命令:
基本用法:
-
let定义:
用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
<script> //let代码块内部定义的变量,与var进行对比 { var a =12; let b =10 console.log(a) //-----12 console.log(b) //-----10 } console.log(a) //-----12 console.log(b) //----- not undefined </script>
-
for
循环很合适使用let
命令。在for
循环体内有效,在循环体外引用就会报错。//let 使用在for循环里面使用不能在外面调用 for(let i=0;i<=5;i++){ console.log(i); //------1,2,3,4,5 } console.log(i); //----- not undefined
-
let在for循环添加事件中最典型的使用方式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <button>1</button> <button>2</button> <button>3</button> <button>4</button> /*创建六个按钮*/ <button>5</button> <button>6</button> <script type="text/javascript"> // let局部引用 var btns = document.getElementsByTagName('button'); for(let i=0;i<btns.length;i++){ //--- 在本行中如果将let更改为var 则点击所有的按钮都会打印数字六,如果使用let,则会根据点击的数字的顺序一次打印,起始数字为0 btns[i].onclick =function(){ console.log(i) } } </script> </body> </html>
-
/ let在for循环作为循环参数的时候其实是两个作用域大括号里面是一个子作用域如果里面再次定义余循环参数相同的变量,则不会产生相互影响
for(let i=0;i<=3;i++){ let i ="a"; console.log(i); //----4个a }
不存在变量提升:
-
let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
console.log(a) // ----not defined let a = 12;
暂时性死区:
-
ES6 明确规定,如果区块中存在
let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用
let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。// 暂时性死区 let 不允许重复定义一个变量 // 大括号括起来的称之为块作用域 有循环,seitch 结构 if结构 for(let i =0 ;i<3;i++){ console.log(i) let i = '123'; } // 暂时性死区 function bar (x=y,y=2){ return[x,y]; } ba=[];
不允许重复定义:
-
暂时性死区 let 不允许重复定义一个变量
for(let i =0 ;i<3;i++){ console.log(i) let i = '123'; }
块级作用域:
-
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景,内层变量可能会覆盖外层变量。
if(true){ function say(){ console.log(1) } } say();
-
ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> // Your ES6 code if(true){ function say(){ console.log(1) } } say(); </script>
注意:为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
- 允许在块级作用域内声明函数。
- 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
- 同时,函数声明还会提升到所在的块级作用域的头部
浏览器环境:
Babel 也可以用于浏览器环境,使用@babel/standalone模块提供的浏览器版本,将其插入网页。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// Your ES6 code
</script>
const命令:
基本用法:
-
const定义:
声明一个只读的常量。一旦声明,常量的值就不能改变。const一旦声明变量,就必须立即初始化,不能留到以后赋值
const PI = 3.1415; console.log( PI ) // ---3.1415 PI = 3; // --- TypeError: Assignment to constant variable.
const foo; //--- SyntaxError: Missing initializer in const declaration //表示,对于const来说,只声明不赋值,就会报错。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。实例与上let例子相似const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。-
本质:
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
const foo = {}; // 为 foo 添加一个属性,可以成功 foo.prop = 123; foo.prop // 123 // 将 foo 指向另一个对象,就会报错 foo = {}; // TypeError: "foo" is read-only
注:常量foo
储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo
指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。