ECMAScript 6 学习笔记:变量定义方法
栏目: JavaScript · 发布时间: 7年前
内容简介:let 声明的变量只在 let 命令所在的代码块内有效。如果在 let 命令所在代码块外调用,则会报错。let 命令的特性导致它非常适合用于 for 循环,每次循环的 i 都是不同的变量,但是每一轮循环都会记住上一轮循环的值,而 var 声明的全局变量,每次循环都是同一个变量:使用传统的 var 定义变量的方式,声明的变量会发生变量提升现象,即定义的变量在编译时被提到了代码的头部,具体表现为变量可以在声明之前使用,值为 undefined。而 let 纠正了这种行为,使用 let 声明的变量一定要在声明后使
ES6 声明变量的六种方法
- var 和 function
- let 和 const
- import 和 class
let 命令
基本用法
let 声明的变量只在 let 命令所在的代码块内有效。如果在 let 命令所在代码块外调用,则会报错。
{
let foo = 1;
var bar = 2;
console.log(foo); // 1
console.log(bar); // 2
}
console.log(foo); // ReferenceError: foo is not defined
console.log(bar); // 2
let 命令的特性导致它非常适合用于 for 循环,每次循环的 i 都是不同的变量,但是每一轮循环都会记住上一轮循环的值,而 var 声明的全局变量,每次循环都是同一个变量:
// 使用 var 定义变量
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[1](); // 无论如何都是 10,因为这里的 i 是全局变量
// 使用 let 定义变量
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[1](); // 输出 1,尽管每次循环的 i 都是重新定义的,但是 for 会记住上一次 i 的值
变量提升
使用传统的 var 定义变量的方式,声明的变量会发生变量提升现象,即定义的变量在编译时被提到了代码的头部,具体表现为变量可以在声明之前使用,值为 undefined。而 let 纠正了这种行为,使用 let 声明的变量一定要在声明后使用,否则会报错。
// 存在变量提升 console.log(foo); // 输出 undefined var foo = 1; // 不存在变量提升 console.log(bar); // 报错 ReferenceError let bar = 1;
暂时性死区
只要块级作用域内存在 let 命令,它所声明的变量就“绑定”这个区域,不再受到外部的影响。ES6 明确规定,如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。这种行为在语法上称为“暂时性死区”。
var foo = 1;
{
foo = 2; // 报错 ReferenceError
let foo; // 由于 let 的存在,区块被绑定,变量无法提升,因此上面会报错
}
重复声明
let 不允许在相同作用域内,重复声明同一个变量
{
let a = 1;
let a = 2; // 报错
}
{
let a = 1;
{
let a = 2; // 不报错
}
}
块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这样可能导致多种问题:
- 内层变量覆盖外层变量
var tmp = 1;
function f() {
console.log(tmp);
if (false) {
var tmp = 2;
}
}
f(); // undefined,因为 if 代码块中的变量发生了变量提升,导致 console.log 无法读取外部变量
- 计数循环变量泄露为全局变量,如上文介绍 for 循环时所提到的那样。
ES6 允许块级作用域的任意嵌套,外层作用域无法读取内层作用域的变量,内层作用域可以定义外层作用域的同名变量。
{
{let insane = 'Hello World'}
console.log(insane); // 报错,外层作用域无法读取内层作用域的变量
};
函数声明
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于 let,在块级作用域之外不可引用。但是在浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于 var 声明的变量。考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。另外,还有一个需要注意的地方。ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
// 不报错
'use strict';
if (true) {
function f() {}
}
// 没有大括号,报错
'use strict';
if (true)
function f() {}
const 命令
const 声明一个只读的常量,一旦声明,常量的值就不能改变,这意味着,const 一旦声明变量,就必须立即初始化,不能留到以后赋值。const 命令的语法特性与 let 命令相同,比如作用域、变量提升规则等。
const PI = 3.1415; PI = 3; // TypeError: Assignment to constant variable.
const 命令保证的是变量指向的内存地址保存的数据不能改动,而对于对象和数组,const 只能保证指向对象和数组的指针不变,因此对于 const 声明的对象和数组是可以使用其内部方法添加数值的,但是无法指向另一个对象或者数组。
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
foo = {123}; // TypeError: "foo" is read-only
如果需要声明一个完全无法改动的对象,应该使用 Object.freeze 方法,将对象和对象的属性全部冻结:
// 使用递归函数将对象和对象的属性全部冻结
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach((key, i) => {
if (typeof obj[key] === 'object') {
constantize(obj[key]);
}
});
};
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 02-GoLang定义变量
- go变量定义
- Golang——变量的声明与定义
- gradle使用技巧(def定义变量 rootProject.ext 添加全局变量)
- 在CoffeeScript中定义私有成员变量
- 在CoffeeScript中定义私有成员变量
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
点击的奥秘:运用说服心理术提升在线影响力(全彩)
Nathalie Nahai(娜塔莉.纳海) / 陈旭 / 电子工业出版社 / 2014-9-1 / 75.00元
用户的每一次点击,不管是在虚拟商店购物,还是在浏览企业网站,或是漫无目的地把玩手机,都蕴藏着基于心理学的无穷奥秘。《点击的奥秘:运用说服心理术提升在线影响力》作者为全球知名的网络心理学家,其在《点击的奥秘:运用说服心理术提升在线影响力》中将心理学、神经科学及行为经济学巧妙地结合在一起,挖掘和提炼出一套行之有效的网络用户引导策略——既涵盖在线说服最新研究动向,也包括最前沿的科技成果,以及其他诸多惊人......一起来看看 《点击的奥秘:运用说服心理术提升在线影响力(全彩)》 这本书的介绍吧!
RGB转16进制工具
RGB HEX 互转工具
UNIX 时间戳转换
UNIX 时间戳转换