原文地址:http://www.cnblogs.com/liuhe688/p/5845561.html

let和const有很多相似之处,先说一说let吧。

1. let添加了块级作用域

我们知道,JavaScript是没有块级作用域的,如果在块内使用var声明一个变量,它在代码块外面仍旧是可见的:

if (true) {
var foo = 3;
}
console.log(foo); // 3 for (var i = 0; i < 9; i++) {
var j = i;
}
console.log(i); // 9
console.log(j); // 8

可以看到,在上面代码中,我们虽然是在块内声明的变量,但代码块执行完毕后,依然可以访问到相应的变量,说明JavaScript中没有块级作用域的。

而ES6规范给开发者带来了块级作用域,如果把var换成let命令,我们就可以获得一个块级变量:

if (true) {
let foo = 3;
}
console.log(foo); // Uncaught ReferenceError for (let i = 0; i < 9; i++) {
let j = i;
}
console.log(i); // Uncaught ReferenceError
console.log(j); // Uncaught ReferenceError

从上面代码可以看出,块内声明的变量,块外是不可见的,如果试图引用一个块内用let声明的变量,就会引发一个异常。

2. let约束了变量提升

在JavaScript中,变量提升是很常见的,例如下面这段代码:

function hoistVariable() {
console.log('foo:', foo); // foo: undefined
var foo = 3;
} hoistVariable();

在代码正式执行之前,编译器将会对代码进行预编译分析阶段,在这个阶段,当前作用域中的变量和函数,将被提升到作用域的顶部。(注:目前的JavaScript引擎大都对源代码进行了编译处理,并且预编译和提升是抽象出来的概念。)

经过预编译之后的代码逻辑如下所示:

function hoistVariable() {
var foo;
console.log('foo:', foo); // foo: undefined
foo = 3;
} hoistVariable();

ES6中的let命令规范了变量的声明,约束了变量提升,也就是说,我们必须先声明,然后才可以使用,下面者段代码将会报错:

function nonHoistingFunc() {
console.log('foo:', foo); // Uncaught ReferenceError
let foo = 3;
} nonHoistingFunc();

正确的使用方式是,永远将变量声明置于当前作用域顶部:

function nonHoistingFunc() {
let foo = 3;
console.log('foo:', foo); // 3
} nonHoistingFunc();

需要注意的是,不管是var还是let,预编译过程中,都发生了变量提升,但与var不同的是,ES6对let进行了约束,其规定,在真正的词法变量声明之前,以任何方式访问let变量都是不允许的,所以从开发人员角度来看,let禁止了变量提升这一行为。

关于这一点,大家可以参考ES6规范中“let和const变量的声明”。

3. let有暂时性死区

只要在块内存在let命令,那么这个变量就绑定到了当前块作用域,不再受外部变量的影响,下面代码将会引发一个错误:

var foo = 3;

if (true) {
foo = 5; // Uncaught ReferenceError
let foo;
}

ES6规定如果块内存在let命令,那么这个块就会成为一个封闭的作用域,并要求let变量先声明才能使用,如果在声明之前就开始使用,它并不会引用外部的变量。

如果把这里的let替换成var,由于不会形成块级作用域,变量的声明其实是与第一行重复了,相当于下面这段代码:

var foo;

foo= 3;

if (true) {
foo = 5;
}

4. let禁止重复声明变量

如上面所述,使用var可以重复声明变量,但let不允许在相同作用域内重复声明同一个变量,下面的代码会引发错误:

// SyntaxError
function func() {
let foo = 3;
var foo = 5;
} // SyntaxError
function func() {
let foo = 3;
let foo = 5;
} // SyntaxError
function func(arg) {
let arg;
}

5. let不会成为全局对象的属性

我们在全局范围内使用var声明一个变量时,这个变量会自动成为全局对象的属性(在浏览器和Node.js环境下,这个全局对象分别是window和global),但let是独立存在的变量,不会成为全局对象的属性:

var a = 3;
console.log(window.a); // 3 let b = 5;
console.log(window.b); // undefined

6. 最后:const命令

以上let所介绍的规则均适用于const命令,不同的是,const声明的变量不能重新赋值,也是由于这个规则,const变量声明时必须初始化,不能留到以后赋值,所以下面的代码是不合法的:

const a = 3;

a = 5;   // Uncaught TypeError: Assignment to constant variable

const b; // Uncaught SyntaxError: Missing initializer in const declaration

以上就是let和const的内容,可以看出,let和const大大改进了ES5的变量机制,使得JS更严谨和规范,随着ES6支持程度的提高,我们应该开始习惯let和const的使用了。

var/let/const区别何在??(转载)的更多相关文章

  1. let、var、const区别(表格比较)

    let.var.const区别(表格比较): 区别项 let var const 作用域 块级作用域 全局作用域或函数作用域 块级作用域 是否有变量提升 无 有 无 是否可重复声明 不可 可以 不可 ...

  2. var let const区别

      var let const 可否同一作用域下声明同名变量 可以 不可以 不可以 声明的变量是否会挂载到window上 会 不会 不会 声明变量是否存在变量提升 存在 不存在(变量必须声明之后才能使 ...

  3. 深度理解js中var let const 区别

    首先要理解js中作用域的概念 作用域:指的是一个变量的作用范围 1.全局作用域 直接写在script中的js代码,在js中,万物皆对象,都在全局作用域,全局作用域在页面打开时创建,在全局作用域中有一个 ...

  4. 在vue中let var 和const 区别

    let和const   使用方法: (1).有没有感觉到在     javascript  使用var会发生变量提升,即脚本开始运行时, 变量已经存在了,但是没有值,所以会输出undefined. 而 ...

  5. JavaScript—var lef const区别

    今天刚刚学JavaScript 因为以前学过.学起来也就轻松.今天在练习.流程控制语句的时候,用WebStrom 写的时候 var 声明变量的时候 下面老是有一条白线.开始以为是开发环境有问题 然后, ...

  6. 小程序里let和var以及const区别

    在JavaScript中有三种声明变量的方式:var.let.const. var:声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循环同样可以使用. [JavaScript] 纯文 ...

  7. Learn-JavaScript-with-MDN 系列文章: 01. var & let & const 对比

    Learn-JavaScript-with-MDN 系列文章: 01. var & let & const 对比 var & let & const 区别 https: ...

  8. JavaScript var, let, const difference All In One

    JavaScript var, let, const difference All In One js var, let, const 区别 All In One 是否存在 hoisting var ...

  9. js var & let & const All In One

    js var & let & const All In One js var & let & const 区别对比 var let const 区别 是否存在 hois ...

随机推荐

  1. ggplot2画histogram(坐标轴刻度值字体大小,坐标轴标题字体大小,柱形宽度,大标题字体大小、居中)

    见链接:https://www.r-bloggers.com/how-to-make-a-histogram-with-ggplot2/ 写的很完整. 此外,关于一些参数的用法: theme(plot ...

  2. bash 6

    1)如果在开发过程中,遇到大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢? 每一行加个#符号太费力了,可以把这一段要注释的代码用一对花括号括起来,定义成一个函数, 没有地方调用这个函数,这块 ...

  3. java 文件创建 调试

    BufferedWriter bw=new BufferedWriter(new FileWriter("/2.txt")); bw.write("hello" ...

  4. Tomcat源码组织结构

    Tomcat 源码组织结构 目录结构 这里所介绍的目录结构,是使用CATALINA-BASE变量定义的路径,如果没有通过配置多个CATALINA-BASE目录来使用多实例,则CATALINA-BASE ...

  5. IIS 错误:由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。

    HTTP 错误 404.3 - Not Found 由于扩展配置问题而无法提供您请求的页面.如果该页面是脚本,请添加处理程序.如果应下载文件,请添加 MIME 映射. 可能是缺少处理程序映射.默认情况 ...

  6. Linux下进程与线程的区别及查询方法

    在平时工作中,经常会听到应用程序的进程和线程的概念,那么它们两个之间究竟有什么关系或不同呢?一.深入理解进程和线程的区别 1)两者概念 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进 ...

  7. TensorFlow入门学习(让机器/算法帮助我们作出选择)

    catalogue . 个人理解 . 基本使用 . MNIST(multiclass classification)入门 . 深入MNIST . 卷积神经网络:CIFAR- 数据集分类 . 单词的向量 ...

  8. Java Web之JSP

    什么是JSP? JSP就是一个可以写Java代码的HTML页面 JSP是什么? JSP是Servlet,JSP的本质就是Servlet Tomcat的web.xml文件下有这样几段代码: 看到下面的通 ...

  9. Hadoop记录-日常运维操作

    1.Active NameNode hang死,未自动切换 #登录当前hang死 Active namenode主机,停止Namenode,触发自动切换.hadoop-daemon.sh stop n ...

  10. canvas绘图history妙用

    function palette(canvas,ctx){ //初始化画布内部元素默认样式 this.strokeColor = 'red'; //默认选中红色触发颜色 this.fillColor ...