一、var
在ES5中,第二层第一类的特性和全局表达式是同构的,用var新闻稿的表达式既是全局表达式,也是第二层表达式
特别注意:第二层第一类,在应用程序自然环境指的是window第一类,在 Node 指的是global第一类
vara =10; console.log(window.a) // 10采用var新闻稿的表达式存有表达式提高的情形
console.log(a) // undefined var a = 20在校对期,C++会将其变为下列继续执行
var a console.log(a) a = 20采用var,他们能对两个表达式展开数次新闻稿,前面新闻稿的表达式会全面覆盖前面的表达式新闻稿
var a = 20 var a = 30 console.log(a) // 30在表达式中采用采用var新闻稿表达式这时候,该表达式是局部性的
var a = 20 function change(){ var a = 30 } change() console.log(a) // 20而如果在表达式内不采用var,该表达式是全局的
var a = 20 function change(){ a = 30 } change() console.log(a) // 30二、let
let是ES6新增的命令,用来新闻稿表达式
用法类似于var,但是所新闻稿的表达式,只在let命令所在的代码块内有效
{ let a = 20 } console.log(a) // ReferenceError: a is not defined.不存有表达式提高
console.log(a) // 报错ReferenceError let a = 2这表示在新闻稿它之前,表达式a是不存有的,这时如果用到它,就会抛出两个错误
只要块级作用域内存有let命令,这个区域就不再受外部影响
var a = 123 if (true) { a = abc // ReferenceError let a; }采用let新闻稿表达式前,该表达式都不可用,也就是大家常说的“暂时性死区”
最后,let不允许在相同作用域中重复新闻稿
let a = 20 let a = 30 // Uncaught SyntaxError: Identifier a has already been declared特别注意的是相同作用域,下面这种情形是不会报错的
let a = 20 { let a = 30 }因此,他们不能在表达式内部重新新闻稿参数
function func(arg) { letarg; }func() // Uncaught SyntaxError: Identifier arg has already been declared三、const
const新闻稿两个只读的常量,一旦新闻稿,常量的值就不能改变
const a = 1 a = 3 // TypeError: Assignment to constant variable.这意味着,const一旦新闻稿表达式,就必须立即初始化,不能留到以后赋值
const a; // SyntaxError: Missing initializer in const declaration如果之前用var或let新闻稿过表达式,再用const新闻稿同样会报错
var a = 20 let b = 20 const a = 30 const b = 30 // 都会报错const实际上保证的并不是表达式的值不得改动,而是表达式指向的那个内存地址所保存的数据不得改动
对于简单类型的数据,值就保存有表达式指向的那个内存地址,因此等同于常量
对于复杂类型的数据,表达式指向的内存地址,保存的只是两个指向实际数据的指针,const只能保证这个指针是固定的,并不能确保改表达式的结构不变
const foo = {}; // 为 foo 添加两个特性,可以成功 foo.prop = 123; foo.prop // 123 // 将 foo 指向另两个第一类,就会报错 foo = {}; // TypeError: “foo” is read-only其它情形,const与let一致
四、差别
var、let、const三者差别可以围绕下面五点展开:
表达式提高暂时性死区块级作用域重复新闻稿修改新闻稿的表达式采用表达式提高
var 新闻稿的表达式存有表达式提高,即表达式可以在新闻稿之前调用,值为undefined
let和const不存有表达式提高,即它们所新闻稿的表达式一定要在新闻稿后采用,否则报错
// var console.log(a) // undefined var a = 10 // let console.log(b) // Cannot access b before initialization let b = 10 // const console.log(c) // Cannot access c before initialization const c = 10暂时性死区
var不存有暂时性死区
let和const存有暂时性死区,只有等到新闻稿表达式的那一行代码出现,才
// var console.log(a) // undefined var a = 10 // let console.log(b) // Cannot access b before initialization let b = 10 // const console.log(c) // Cannot access c before initialization const c = 10块级作用域
var不存在块级作用域
let和const存有块级作用域
// var { var a = 20 } console.log(a) // 20 // let { let b = 20 } console.log(b) // Uncaught ReferenceError: b is not defined // const { const c = 20 } console.log(c) // Uncaught ReferenceError: c is not defined重复新闻稿
var允许重复新闻稿表达式
let和const在同一作用域不允许重复新闻稿表达式
// var var a = 10 var a = 20 // 20 // let let b = 10 let b = 20 // Identifier b has already been declared // const const c = 10 const c = 20 // Identifier c has already been declared修改新闻稿的表达式
var和let可以
const新闻稿两个只读的常量。一旦新闻稿,常量的值就不能改变
// var var a = 10 a = 20 console.log(a) // 20 //let letb =10 b = 20 console.log(b) // 20 // const const c = 10 c = 20 console.log(c) // Uncaught TypeError: Assignment to constant variable采用
能用const的情形尽量采用const,其他情形下大多数采用let,避免采用var