ES6中新的变量声明方式介绍(附代码)
在ES5中,变量声明只要var和function乃至隐式声明三种,在ES6中则增添了let、const、import和class四种。
1. let
1.1 块级作用域
let声明的变量的作用域是块级作用域(这个特性有点相似于后台说话),ES5 并没有块级作用域,只要函数作用域和全局作用域。
{ let a = 'ES6'; var b = 'ES5'; } console.log(b) // ES5 console.log(a) // ReferenceError: a is not defined.
那么let的块级作用域有什么好处呢?
let非常适合用于 for轮回内部的块级作用域。JS中的for轮回体比力非凡,每次施行都是一个全新的独立的块作用域,用let声明的变量传入到 for轮回体的作用域后,不会发生改动,不受外界的影响。看一个常见的面试问题:
for (var i = 0; i <10; i++) { setTimeout(function() { // 同步注册回调函数到异步的宏任务队列。 console.log(i); // 施行此代码时,同步代码for轮回已经施行完成 }, 0); } // 输出结果 10 (共10个) // 这里变量为i的for轮回中,i是一个全局变量,在全局范畴内都有效,所以每一次轮回,新的i值都会覆盖旧值,致使最后输出的是最后一轮i的值,即i的终究结果为10,实际上都是console.log(10)。触及的知识点:JS的事件轮回机制,setTimeout的机制等
把 var改成 let声明:
for (let i = 0; i < 10; i++) { setTimeout(function() { console.log(i); //当前的i仅在本轮的轮回中有效,就是说每一次轮回,i其实都是一个新发生的变量。 //用 let 声明的变量 i 只作用于轮回体内部,不受外界干扰。 }, 0); } // 输出结果: 0 1 2 3 4 5 6 7 8 9
1.2 临时性死区(Temporal Dead Zone)
在一个块级作用域中,变量独一存在,一旦在块级作用域中用let声明了一个变量,那么这个变量就独一属于这个块级作用域,不受外部变量的影响,如下面所示。
var tmp = 'bread and dream'; if(true){ tmp = 'dream or bread'; //ReferenceError let tmp; }
这个例子中tmp = 'dream or bread'的赋值会报错,由于在if块中的let对tmp变量停止了声明,致使该tmp绑定了这个作用域,而let暂时死区致使了并不克不及在声明前使用,所以在声明前对变量赋值会报错。
临时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不成猎取,只要比及声明变量的那一行代码显现,才可以猎取和使用该变量。
临时性死区的意义也是让我们标准化代码,将所有变量的声明放在作用域的最开端。
1.3 不同意反复声明
(1) 在雷同的作用域内,用let声明变量时,只同意声明一遍,但 var是可以屡次声明的。大家都知道ES5 屡次声明会造成变量覆盖并且不会报错,这就给调试增添了难度,而let能够直接抹杀这个问题在摇篮之中,由于会直接报错。
// 不报错 function demo() { var a = 'bread and dream'; var a = 'dream or bread'; } // 报错,Duplicate declaration "a" function demo() { let a = 'bread and dream'; var a = 'dream or bread'; } // 报错,Duplicate declaration "a" function demo() { let a = 'bread and dream'; let a = 'dream or bread'; }
(2) 不克不及在函数内部从新声明参数:
function demo1(arg) { let arg; // 报错 } demo1() function demo2(arg) { { let arg; // 不报错 } } demo2()
2. const
2.1 用于声明常量
const声明的常量是不同意改动的,只读属性,这意味常量声明时必需同时赋值, 只声明不赋值,就会报错,平常常量以大写字母命名。
const Person; // 错误,必需初始化 const Person = 'bread and dream';// 准确 const Person2 = 'no'; Person2 = 'dream or bread'; //报错,不克不及从新赋值
这样做的两个好处:一是阅读代码的人立即会意识到不该该修改这个值,二是防止了无意间修改动量值所致使的错误。比方我们使用nodejs的一些模块的时候,我们只是使用对应的模块(如http模块),但是并不需要修改nodejs的模块,这个时候就可以声明成const,增添了代码的可读性和幸免错误。
2.2 支撑块级作用域
const和let相似,也是支撑块级作用域.
if (true) { const MIN = 5; } MIN // Uncaught ReferenceError: MIN is not defined
2.3 不支撑变量晋升,有临时性死区
const声明的常量也是不晋升,一样存在临时性死区,只能在声明的位置后面使用。
if (true) { console.log(MIN); // ReferenceError const MIN = 5; }
2.4 非凡状况
假如声明的常量是一个对象,那么关于对象本身是不同意从新赋值的,但是关于对象的属性是可以赋值的。
const obj = {}; obj.a = 'xiao hua'; console.log(obj.a); //'xiao hua'
实际上const能包管的,并不是变量的值不得改动,而是变量指向的阿谁内存地址所留存的数据不得改动。
关于简便类型的数据(数值、字符串、布尔值),值就留存在变量指向的阿谁内存地址,因此等同于常量。
但关于复合类型的数据(主如果对象和数组),变量指向的内存地址,留存的只是一个指向实际数据的指针。
至于它指向的数据构造是不是可变的,就完全不克不及操纵了。因此,将一个对象声明为常量必需非常当心。
假如要彻底将对象冻结(不成修改其属性),应当使用Object.freeze(obj)办法。同理,数组也是一样的。
3. import
ES6采纳import来代替node等的require来导入模块。
import {$} from './jquery.js'
$对象就是jquery中export显露的对象。
假如想为输入的变量从新取一个名字,import命令要使用as关键字,将输入的变量重命名。
import { JQ as $ } from './jquery.js';
留意,import命令具有晋升结果,会晋升到整个模块的头部,第一施行。
4. class
ES6引入了类的概念,有了class这个关键字。类的本色还是函数对象。
先定义一个类:
//定义类 class Animal { constructor(name, age) { this.name = name; this.age = age; } setSex(_sex) { this.sex=_sex; } }
constructor办法,就是结构办法,也就是ES5时代函数对象的主体,而this关键字则代表实例对象。
上面的类也可以改成ES5的写法:
function Animal(name, age){ this.name = name; this.age = age; } Animal.prototype.setSex = function (_sex) { this.sex=_sex; }
其实,大多数类的特性都可以通过此前的函数对象与原型来推导。
生成类的实例对象的写法,与ES5通过结构函数生成对象完全一样,也是使用new命令。
class Animal {} let dog = new Animal();
在类的实例上面调取办法,其实就是调取原型上的办法,由于类上的办法其实都是增加在原型上。
Class其实就是一个function,但是有一点不一样,Class不存在变量晋升,也就是说Class声明定义必需在使用此前。
5.总结
在ES6此前,JavaScript是没有块级作用域的,假如在块内使用var声明一个变量,它在代码块外面仍然是可见的。ES6标准给开发者带来了块级作用域,let和const都增加了块级作用域,使得JS更严谨和标准。
let 与 const 雷同点:
块级作用域
有临时性死区
束缚了变量晋升
制止反复声明变量
let 与 const不一样点:
const声明的变量不克不及从新赋值,也是由于这个规则,const变量声明时必需初始化,不克不及留到今后赋值。
合理的使用ES6新的声明方式,不管是面试还是工作中都有实际的利用,特别是工作中,大家必然要尽量的多使用新的声明方式,不单可以让代码更标准,更可以幸免不必要的bug,白费调试时间,进而提高工作效力。
本篇文章到这里就已经全部完毕了,更多其他出色内容可以关注PHP中文网的JavaScript视频教程栏目!
以上就是ES6中新的变量声明方式介绍(附代码)的具体内容,更多请关注百分百源码网其它相关文章!