es5与es6的变量声明和作用域的异同

原创 2016年12月19日 17:17:11

在es6没出来之前,js的作用域只有两种顶层作用域和函数作用域,但是es6的出现,让js的变量作用域有了新的存在形式:块级作用域

在了解块级作用域之前,还是得先复习下es5的变量声明与作用域

变量声明:

我们都知道js使用var关键字来声明一个变量,如果不使用var关键字来声明变量就表示声明的变量是顶层变量(虽然这不是一个严谨的写法,在es5的严格模式下会抛出异常)。当我们直接声明一个变量的时候就相当于是在window下挂载了一个新变量。例如:

a = 1;
window.a = 1;
//上述两种写法是一样的。但是在如下情况第一种写法是错误的。

'use strict'
a = 1; //Uncaught ReferenceError: a is not defined(…)

变量提升:

在js中所有由var声明的变量都会提升到作用域的顶部进行声明,然后再在声明的地方进行赋值。还是直接看代码吧!

var a = 1;
function foo(){
    console.log(a);  //undefined;
    //因为该函数内重新声明了一次a变量,虽然在当前语句的后面才a变量,但是变量声明会被提升到当前函数作用域的顶部。
    //注意这里只是将声明提升到了顶部,而没有进行赋值,赋值还是在声明变量行进行,所有后面的console.log才会打印出3。
    var a = 3;
    console.log(a);  //3
}
foo();

有一点需要注意的就是,var声明函数变量时,和直接使用function定义函数时效果是不一样的。var只能把变量名的声明提前,而使用function定义函数时,函数的初始化也会被提前,所以不论你何时使用function声明函数,只要有声明调用时都不会产生错误,而使用var形式的函数表达式,在赋值之前调用都会找不到函数。

fun(); //Uncaught TypeError: fun is not a function(…)
var fun = function () {
    alert(1);
}

-----------

fun(); //1
function fun() {
    alert(1);
}

还有一点就是重复使用同一函数名的两个函数,后声明的生效

function fun() {
    return 1;
}

console.log(fun());  //2

function fun() {
    return 2;
}

es6如何声明变量:

es6引入了两种新的声明变量的方式:let与const。

  1. let
    使用let声明的变量与var声明的变量类似,唯一的区别就是只能在当前块级作用域中有用。先看看什么是块级作用域,所谓块级作用域,就是当前的代码块,简单来说就是一对大括号中的内容就叫做块级作用域,比如一个if语句中的内容,一个for循环中的内容。
{
    var  a = 1;
    let b = 2;
}

console.log(a); //1
console.log(b); //b is not defined(…)

再看一个例子:

if(true){
    let a = 1;
}

console.log(a); //a is not defined(…)

引入块级作用域有很多好处,比如解决了之前for循环定义的变量造成全局污染的问题,而且不必再使用闭包来保存必要的变量,因为各个代码块的变量相互独立,不会造成全局变量的污染。

//es5:
for(var i=0;i<5;i++){

}
console.log(i); //5


//es6:
for(let i=0;i<5;i++){

}
console.log(i); //i is not defined(…)
//es5:
var arr = []
for(var i=0;i<5;i++){
    arr[i] = function(){
        alert(i);
    }
}
arr[3](); //5


//es6:
let arr = []
for(let i=0;i<5;i++){
    arr[i] = function(){
        alert(i);
    }
}
arr[3](); //3
  1. const
    使用const声明的变量与let声明的变量类似,也只能在块级作用域中有用,不同的是const声明的变量是只读的,也就是声明过后就不能被修改了。
const PI = 3.1415;
PI = 3; // Assignment to constant variable.

let与const没有变量提升:

之前看到var声明的变量都会提升到,但是使用let与const声明的变量没有这个特点。

{
    console.log(a); //a is not defined(…)
    let a = 1;

    -------

    console.log(b); //b is not defined(…)
    const b = 1;
}

如果在申明变量之前,就调用该变量就会产生错误(ReferenceError)。在上面的案例中let a之前我们调用了a变量,但是该变量是不可用的,我们把该变量不可用的区域叫做“暂时性死区”(temporal dead zone,简称TDZ)。这样做也有好处,在没有声明变量之前就不能使用该变量从而可以减少一些代码运行的错误,像es5如果使用了也难以发现错在哪里。

不允许重复的变量声明:

{
    let a = 1;
    let a = 2; //Identifier 'a' has already been declared
}

重复在同一个块级作用域内声明同一个变量会有语法错误。


es6为js的变量提供了两种新的变量声明方式(let与const),并且提供了新的块级作用域。虽然这给之前js的灵活性带来了一定的限制,但是这根本不算什么,太灵活也会造成很多的混乱,块级作用域的引入让我们不必再使用闭包的方式来保存一些变量了。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

ES 5、ES 6变量和函数声明以及作用域总结

变量提升JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明。var v = "hello"; (fun...

ES6箭头函数和它的作用域

在ES6很多很棒的新特性中, 箭头函数 (或者大箭头函数)就是其中值得关注的一个! 它不仅仅是很棒很酷, 它很好的利用了作用域, 快捷方便的在现在使用以前我们用的技术, 减少了很多代码……但是如果你不...
  • hacke2
  • hacke2
  • 2014-11-10 10:19
  • 5418

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

ES6和ES5特性对比

ES6和ES5特性对比:let vs var

ES5与ES6的对比不同点

很多React/React Native的初学者都被ES6的问题迷惑:各路大神都建议我们直接学习ES6的语法(class Foo extends React.Component),然而网上搜到的很多教...

es5与es6的变量声明和作用域的异同

在es6没出来之前,js的作用域只有两种顶层作用域和函数作用域,但是es6的出现,让js的变量作用域有了新的存在形式:块级作用域。

JavaScript没有块级作用域

1.声明变量 使用var声明的变量会自动被添加到最接近的环境中。在函数内部,最接近的环境就是函数的局部环境;在with语句中,最接近的环境就是函数环境。如果初始化变量时没有使用var声明,该变量会自...

ES6的变量声明

在ES5中,变量声明只有var和function以及隐式声明三种,在ES6中则增加了let,const,import和class四种,以下来介绍着七种变量的声明。 var ES5中最原始的变量...

ES6的变量声明

在ES5中,变量声明只有var和function以及隐式声明三种,在ES6中则增加了let,const,import和class四种,以下来介绍着七种变量的声明。 var ES5中最原...

ES6块级作用域及新变量声明(let)

很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}” 却限定不了var的作用域。用var声明的变量具有变量提升(declaration hoist...

JS的解析原理和变量作用域

从词法作用域和词法环境的角度深层次阐述了JS解析原理和变量作用域
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)