JavaScript ES6中的简写语法总结与使用技巧(15)
下面的代码则是可行的:
function readName() { return name } let name console.log(readName()) // <- undefined
TDZ的存在使得程序更容易报错,由于声明提升和不好的编码习惯常常会存在这样的问题。在ES6中则可以比较好的避免了这种问题了,需要注意的是let声明的变量同样存在声明提升。这意味着,变量会在我们进入块作用域时就会创建,TDZ也是在这时候创建的,它保证该变量不许被访问,只有在代码运行到let声明所在位置时,这时候TDZ才会消失,访问限制才会取消,变量才可以被访问。
Const 声明
const声明也具有类似let的块作用域,它同样具有TDZ机制。实际上,TDZ机制是因为const才被创建,随后才被应用到let声明中。const需要TDZ的原因是为了防止由于变量提升,在程序解析到const语句之前,对const声明的变量进行了赋值操作,这样是有问题的。
下面的代码表明,const具有和let一致的块作用域:
const pi = 3.1415 { const pi = 6 console.log(pi) // <- 6 } console.log(pi) // <- 3.1415
下面我们说说const和let的主要区别,首先const声明的变量在声明时必须赋值,否则会报错:
const pi = 3.1415 const e // SyntaxError, missing initializer
除了必须初始化,被const声明的变量不能再被赋予别的值。在严格模式下,试图改变const声明的变量会直接报错,在非严格模式下,改变被静默被忽略。
const people = ['Tesla', 'Musk'] people = [] console.log(people) // <- ['Tesla', 'Musk']
请注意,const声明的变量并非意味着,其对应的值是不可变的。真正不能变的是对该值的引用,下面我们具体说明这一点。
通过const声明的变量值并非不可改变
使用const只是意味着,变量将始终指向相同的对象或初始的值。这种引用是不可变的。但是值并非不可变。
下面的例子说明,虽然people的指向不可变,但是数组本身是可以被修改的。
const people = ['Tesla', 'Musk'] people.push('Berners-Lee') console.log(people) // <- ['Tesla', 'Musk', 'Berners-Lee']
const只是阻止变量引用另外一个值,下例中,尽管我们使用const声明了people,然后把它赋值给了humans,我们还是可以改变humans的指向,因为humans不是由const声明的,其引用可随意改变。people 是由 const 声明的,则不可改变。
const people = ['Tesla', 'Musk'] var humans = people humans = 'evil' console.log(humans) // <- 'evil'
如果我们的目的是让值不可修改,我们需要借助函数的帮助,比如使用Object.freeze: