ES6学习1(let与const)
来源:互联网 发布:知乎 股票宏观资讯 编辑:程序博客网 时间:2024/04/29 18:01
let命令
基本用法
let命令用来声明变量,它的用法类似于var,但是所声明的变量只在let命令所在的代码块内有效。
{ let a = 10; var b = 1;}a // ReferenceError: a is not defined.b // 1
for循环的计数器就很适合使用let,这样计数器的值在外面就无法访问到了。
不存在变量提升
let不像var会发生变量提升,var即便是在声明前使用,其声明还是存在的,但是赋值不会被提前。
let连声明都不会提升。
console.log(foo); // 输出undefinedconsole.log(bar); // 报错ReferenceErrorvar foo = 2;let bar = 2;
暂时性死区
ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
var tmp = 123;if (true) { tmp = 'abc'; // ReferenceError let tmp;}
在代码块内,在使用let声明变量前,变量都是不可用的,这就称为暂时性死区(temporal dead zone,简称TDZ)。
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123}
在以前,typeof是一个安全的操作,但是再也不是了。因为如果这样的话无论如何都会报错:
typeof x; // ReferenceErrorlet x;
如果一个变量根本就没有声明,使用typeof反而是不会报错的只会返回undefined。
有的暂时性死区比较隐蔽:
function bar(x = y, y = 2) { return [x, y];}bar(); // y is not defined
不允许重复声明
let不允许在相同的作用域内重复声明同一个变量
// 报错function () { let a = 10; var a = 1;}// 报错function () { let a = 10; let a = 1;}
块级作用域
不存在块级作用域的问题
在ES5中只有全局作用域和函数作用域,由于不存在块级作用域。会有一些问题。
内层变量覆盖外层变量
var tmp = new Date();function f() { console.log(tmp); if (false) { var tmp = "hello world"; }}f(); // undefined
由于变量提升,if里面的tmp被提升到了函数f的作用域的顶部,在使用log输出tmp时,tmp已经被覆盖为内层的tmp且并未赋值,于是就输出了undefined。
循环变量泄露为全局变量
这个问题之前就提到了,就是for中的i由于没有块级作用域,在for循环外面也访问的到。
ES6的块级作用域
let实际上为JS增加了块级作用域,不会因为内层的变量影响外层的。
function f1() { let n = 5; if (true) { let n = 10; } console.log(n); // 5}
而且还规定函数本身的作用域在其所在的块级作用域内
function f() { console.log('I am outside!'); }(function () { if(false) { // 重复声明一次函数f function f() { console.log('I am inside!'); } } f();}());
在ES5中输出I am inside!,因为函数声明提升到了作用域的顶部,在ES6中会得到I am outside!因为函数被限制在了块级作用域中。
{ let a = 'secret'; function f() { return a; }}f(); // 报错
这样就可以:
let f;{ let a = 'secret'; f = function () { return a; };}f(); // "secret"
const命令
const声明一个只读的常量。一旦声明就不能改变。这也就意味着一旦声明就必须马上初始化。与let相同,声明只在块级作用域内有效,不可重复声明,不提升。
对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址,const只保证对象名指向的地址不变,不保证地址的数据不变。
const foo = {};foo.prop = 123;foo.prop// 123foo = {}; // TypeError: "foo" is read-onlyconst a = [];a.push("Hello"); // 可执行a.length = 0; // 可执行a = ["Dave"]; // 报错
如果想冻结一个对象,可以使用freeze方法将对象本身和其属性全部冻结:
var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, value) => { if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); } });};
全局对象的属性
全局对象是最顶层的对象,浏览器中是window对象,在Node中指的是global。
在ES5中全局变量和全局对象的属性是等价的,这样其实并不是很好。未声明的全局变量就自动成为了全局变量,也就成为了全局对象window的属性。这样带来了两个问题,编译时使用未声明变量不会报错;开发时很容易不知不绝就创建了一个全局变量(比如打错了)。
window.a = 1;console.log(a); // 1a = 2;console.log(window.a) // 2
ES6为了改变这一点,规定var,function命令声明的全局变量依然是全局对象的属性,而let,const,class命令声明的全局变量不属于全局对象的属性。
//经测试,5.8.0版本的node,var声明的全局变量也不会变成全局对象的属性,this.a也会输出undefinedvar a = 1;console.log(this.a) // 1let b = 1;console.log(this.b) // undefined
- ES6学习1(let与const)
- ES6 学习笔记 1 let与const
- es6学习笔记1-let与const
- es6学习-1 let&const
- ES6学习之一let与const
- es6学习-let,const
- ES6---let与const
- ES6-let 与 const
- ES6学习笔记1--let、const
- 1、let和const -ES6学习笔记
- ES6学习笔记(一)let const
- ES6(let 、const)
- 【ES6学习】— (1)ES6简介、let与const命令以及变量的解构赋值
- ES6学习-let和const
- ES6学习笔记 (let、const)
- ES6学习笔记-Let&Const
- ES6之 let与const
- ES6(一)const与let
- activemq 入门学习
- 2016年6月,我们毕业了~~~
- php错误级别的设置方法
- Linux常用命令:ifconfig命令
- 加载so库错误问题“couldn't find "libbmob.so"”
- ES6学习1(let与const)
- 您所不知道的nil/Nil/NULL/NSNull的空与空
- number——input新属性,提交时自动检测数字格式,大小
- Android Studio 进行单元测试时报 A fatal error has been detected by the Java Runtime Environment:
- JQuery 常用方法基础教程
- Linux常用命令:route命令
- 矩阵特征值分解与奇异值分解含义解析及应用
- Mysql存储过程
- dubbo Address already in use: bind 解决方案