Javascript的宣告方式
在很久很久以前...
其实也没有多久啦。
ES6之前宣告的方法都是用var
宣告,这也导致很多有趣的事情发生。
所以在ES6之后才导入const
跟let
这两个宣告的方法。
当今天想要宣告一个常数,会使用const
。换而言之要宣告一个变数就会用let
。
常数跟变数的差别在于:
常数=常数就是记忆体中可以存放资料的地方,但通常不会轻易去改变常数的值。
变数=变数也是记忆体中可以存放资料的地方,而其所存放的值可以被改变。
额外补充
JS当初在设定时比较随性,所以其实可以不用宣告变数就可以拿来用。
只是如果你没有宣告,它就会变成一个全域变数而已。
听起来好像没什么大不了的,但通常不建议这么做,客倌请小心服用啊
这会导致全域物件的污染,所以千千万万不要在还没宣告变数的状况下就拿来用!
var跟let的差别
我猜看到这边一定会想说竟然都已经有var了,为什么要再产生一个let呢?
既生瑜,何生亮!
因为JS在执行程式的时候会经历两个阶段:
建立期:JS会先分配记忆体给宣告的变数及函式,其中函式又会比变数优先被宣告。
在这段期间又会分为两个过程,(依照程式码由上至下的顺序)
注册名称 = JS 会宣告变数,但不会赋值给变数。
初始化 = 因为没有值的关係,这个变数的值会是undefined。(这边回应到上一篇文章
执行期:执行程式码。
在执行期也会做两件事情(依照程式码由上至下的顺序),把宣告变数里的值指定给变数,执行函式。
过去在使用var宣告的时候会有以下这种状况
console.log(a)var a = 3// 印出 undefined// 程式码由上开始往下读取// 建立期会跳过 console.log// 建立期执行注册名称 var a 并初始化 var a = undefined// 回到 console.log ,执行程式码 undefined => 被印出// 执行程式码 a = 3
这种状况也称为变数提升(Hoisting),这也是JS才会出现的独有状况。
但是后来到ES6后就不会有这种状况发生了,因为有let跟const的诞生来拯救众生。
如果上面那段程式码换成下面这样:
console.log(a)let a = 3// 会喷错告诉你 ReferenceError: Cannot access 'a' before initialization
TemporalDeadZone暂时死区
差别在于用var
在宣告时变数会变成全域变数,用let
宣告时变数会变成区域变数。
JS 在初始化时会用一个 TDZ (TemporalDeadZone暂时死区) 把变数盖住,当给予值后才能把盖子打开。就不会有出现先预设给undfined的问题。
其实都有变数提升的设计,但多了一个TDZ的设计结果就会不一样,因为变数储存在记忆体的位置不同。var
没有TDZ所以在初始化后已经被赋予undefined并储存进记忆体中。但let跟const都是初始化后被TDZ盖住并存进TDZ中,直到你赋予它值才可以拿出来。
重複宣告
上面有提到常数跟变数的差别在于值是否可以改变,接下来在做一下讨论
const a = 1;const a = 2;console.log(a); //SyntaxError: Identifier 'a' has already been declared //大概就是说a这个常数已经被宣告。
let b = 1;let b = 2;console.log(b); //SyntaxError: Identifier 'b' has already been declared //大概就是说b这个变数已经被宣告。
修但几勒,上面不是说变数的值可以更改吗?你这个渣男是不是在欺骗我的感情啊!
其实如果要修改这个值要用别的方法啦!我才不是什么爱情的骗子。来示範一下
let b = 1;b = 2;console.log(b); //印出2 //这样就可以更改b这个变数的值
这几天会在整理并在下一篇纪录Scope chain
参考文献
网页前后端宝石库-矿坑补完计画系列 第 11 篇 Day 11 JavaScript var vs let (1)