资讯专栏INFORMATION COLUMN

ES6系列文章 块级作用域

赵连江 / 1975人阅读

摘要:声明之函数作用域和全局作用域。块级作用域不能重复声明临时性死区等特性用来解决变量存在的种种问题。块级作用域终于在外面访问不到了。一些常量声明使用声明的变量名全部大写。

ES5之前javascript语言只有函数作用域和全局作用域,使用var来声明变量,var声明的变量还存在变量提升使人困惑不已。我们先来复习一下ES5的var声明,再对比学习let和const 。

var var声明之函数作用域和全局作用域。

来段代码体会一下:

function getName() {
    if (1 + 1 === 2) {
        var name = "xixi";
    }

    console.log(name);
}

getName();//xixi

在c或java语言中name本应该只在if块中使用的,但是在if的外面也可以访问到,这个就是 js没有块级作用域的一种体现。这个弊端在for循环中体现的十分明显:

for (var i = 0; i < 10; i ++) {
    // ...
}

console.log(i);// 10

var i的本意是声明个临时变量i,用来遍历数组等,本不应该在for循环的外部访问到,但现在却可以被访问到你说闹不闹心?好一点的程序员会用立即执行函数来模拟块级作用域,原来的我会注意一下尽量不使用相同的变量名?。

(function() {
    for (var i = 0; i < 10; i ++) {
        // ...
    }
})();

console.log(i);// undefined

以上:大家知道了 js 没有块级作用域。

变量可以重复声明
var name = "xixi";
console.log(name);// xixi
var name= "一步";
console.log(name);// 一步

不报错,困惑不困惑,这个就是变量可以重复声明。

变量提升
function getName() {
    console.log(name);
    var name = "xixi";
    // ...
}

getName();// undefined

console.log打印name为undefined。为啥不报错呢,对于一直使用js语言的人来说这个现象还好理解,如果是后台转前端的人来说估计得骂人了。这就是所谓的变量提升。简单的向大家解释一下吧。

var name = "xixi";

这是一条被我们写烂了的语句,包含两个过程:var name; name = "xixi";分别为变量声明和变量初始化。

变量提升: 无论变量声明var name;处于什么位置,都会被提到作用域的顶部进行。

let

ES6为让变量生命周期更加可控,引入两个非常好的特性letconst。块级作用域、不能重复声明、临时性死区等特性用来解决 var 变量存在的种种问题。

块级作用域
function getName4ES6() {
    if (1 + 1 === 2) {
        let name = "xixi";
    }

    console.log(name);
}

getName4ES6(); // undefined

终于在{}外面访问不到name了。for循环也变的简单了,大家试一下将for循环的var换成 let.

同一块级作用域内不能重复声明变量
function redefineValue() {
    let name = "xixi";
    let name = "一步";
}

redefineValue();// Uncaught SyntaxError: Identifier "name" has already been declared

重复声明会报错

{
    let name = "xixi";
    console.log(name);// xixi
    {
        let name = "yibu";
        console.log(name); // yibu
    }
}

注意: 在 ES6中,{}就是一个块级作用域。

临时性死区
function getName4ES6() {
    console.log(name);
    for (let i = 0; i < 10; i ++) {

    }
    let name = "xixi";
    // ...
}

getName4ES6();// Uncaught ReferenceError: name is not defined

在上文ES5中,name还会存在变量提升,值为undefined。ES6中又报错了。怎么解释呢?。。。。这个就是临时性死区的概念,在作用域块中不可以在变量声明前就使用变量,若使用是会出错的。

javascript引擎在发现变量声明时,要么将变量声明提升到作用域的顶部(var声明变量时),要么将变量放在临时性死区中(let、const声明变量时),访问临时性死区中的变量会触发运行时错误。

const

const和let同样具有块级作用域,不能重复声明,临时性死区的概念。它还具有两个特有的特性:声明的同时必须初始化、变量引用不可以改变。

声明的同时必须初始化
const name;//Uncaught SyntaxError: Missing initializer in const declaration

不赋值,就报错。这个也很好理解const的本意就是用来定义常量,不可变的值。若不在声明时给出初始值以后就再也没有机会了。

值不可变
const name = "x9x9";
name = "yyy";// Uncaught SyntaxError: Invalid or unexpected token

那么对象会怎样呢?

const person = {
    name: "lala",
    age: 40
};

person = {};// VM1042:6 Uncaught TypeError: Assignment to constant variable. at :6:8

引用是不可变的,那我们在看看对象的属性值是什么情况吧~

person.name = "yoyo";
console.log(person);// {name: "yoyo", age: 40}

没有报错,对象引用不可改变,对象属性可以变更。

let vs const

大家可能会困惑,什么时候使用let,什么时候使用const。let能做的const好像都可以。网上有一种流行做法:能用const就绝不用let,简单粗暴,不过很好用。
个人看法:若变量在后续方法中会被改变,就使用let。一些常量声明使用const, const声明的变量名全部大写。代码中的变量,如果是let声明的就代表其可变,若是const声明的,不论是简单数据类型还是引用类型变量就都不要改变它的值。这样,程序会更加的健壮,大家合作起来也比较方便。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88863.html

相关文章

  • ES6系列之 let 和 const

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。这在语法上,称为暂时性死区,简称。这表明函数内部的变量与循环变量不在同一个作用域,有各自单独的作用域。系列文章系列文章地址 showImg(https://segmentfault.com/img/bVbrjjC); 为什么需要块级作用域 ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合...

    libxd 评论0 收藏0
  • JavaScript基础系列---变量及其值类型

    摘要:但对于引用类型的数据主要是对象和数组,变量指向的内存地址,保存的只是一个引用地址指针,只能保证这个引用地址指针是固定的,至于它指向的堆内存中的存储的值是不是可变的,就完全不能控制了。 基础概念 变量是存储信息的容器,这里需要区分一下:变量不是指存储的信息本身,而是指这个用于存储信息的容器,可以把变量想象成一个个用来装东西的纸箱子 变量需要声明,并且建议在声明的同时进行初始化,如下所...

    sugarmo 评论0 收藏0
  • ES6走走看看—由块级作用引出的一场变革

    摘要:块级声明块级声明是用于声明在指定块的作用域之外无法访问的变量。美元符号可以放到任何一个位置,甚至单独一个美元符号。块级函数从开始,在严格模式下,块里的函数作用域为这个块。 持续更新的github笔记,链接地址:Front-End-Basics 此篇文章的笔记地址:字符到底发生了什么变化 ES6走走看看系列,特别鸣谢奇舞读书会~ 块级作用域又称词法作用域,存在于: 函数内部(...

    荆兆峰 评论0 收藏0
  • ES6系列】变量与块级作用

    摘要:不允许在相同作用域内,重复声明同一个变量。如但是在中则不再必要了,我们可以通过块级作用域就能够实现本次主要针对中的变量和块级作用域进行了梳理学习,并且通过与的实现方式进行了对比,从而看出其变化以及快捷与便利。 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可...

    PascalXie 评论0 收藏0
  • 【进阶2-3期】JavaScript深入之闭包面试题解

    摘要:闭包面试题解由于作用域链机制的影响,闭包只能取得内部函数的最后一个值,这引起的一个副作用就是如果内部函数在一个循环中,那么变量的值始终为最后一个值。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第二期,本周的主题是作用域闭包,今天是第8天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了...

    alanoddsoff 评论0 收藏0

发表评论

0条评论

赵连江

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<