var,let与const的恩怨情仇
以下内容源自《深入理解 ES6》的书,有更多兴趣的建议看看。
三角关系其实很清晰
js:喵蛋,你们谁敢说变量声明比我“优秀”的?
php:世界“第一”的我表示,不敢。
java:世界最“牛”的我表示,不敢。
python:世界最“简单”的我表示,不敢。
c:傻逼……
var
谨记一点:var 声明的变量永远声明在当前所在 函数 的作用域内,非函数作用域内声明还是被当做声明在所在函数内,如下伪代码:
function() {
var a = 1
if(any) {
var b = 1
console.log(a, b,) // 1, 1
} else {
console.log(a, b) // 1, undefined,注意不是not defined
}
console.log(b) // undefined
}
其中 var b = 1
被分解为:var b; b = 1
,而 var b
部分被提升(hoisting,跟我读:好意思听?)到 function 里面了,明白?如下:
function() {
var a
var b
a = 1
if(any) {
b = 1
console.log(a, b,) // 1, 1
} else {
console.log(a, b) // 1, undefined,注意不是not defined
}
console.log(b) // undefined
}
与 window 的关系
在浏览器环境下,全局默认有个 window 对象,因为 var 的 hoisting 存在,会使得 var 个东西变成 window 的,这不是坏事,很多人已经习惯这么干了,比如:
var test = 1
window.test // 1
if(1) {
var test1 = 1
}
window.test1 // 1
这个好处是很方便获取变量,坏处就是容易把 window 的自带属性给覆盖了,如下:
var RegExp = '1'
window.RegExp // 1
大哥,RegExp 是很重要的对象好吗?
let
首先,let 就锁作用域了,跟 var 不同,不会 hoisting(读一遍),而且是根据代码块,而不是函数作用于,也就是说,if,for 等等都会锁作用域,如下伪代码:
function() {
let a = 1
if(any) {
let b = 1
console.log(a, b,) // 1, 1
} else {
console.log(a, b) // 1, not defined,其实这里是报错……
}
console.log(b) // not defined,其实这里是报错……
}
其次,let 不允许同作用域内重复声明,注意,同作用域,伪代码:
function() {
let a = 1
let a = 2 // 报错
if(any) {
let a = 3 // 没错,此a非彼a了,当前代码块内用到的都是这个a
}
}
暂时性死区
temporal dead zone,TDZ
这个名字非常非常的头(shuai)疼(qi),看这个代码:
if(1) {
console.log(typeof a) // undefined,hoisting,ok?
var a = 1
}
if(1) {
console.log(typeof a) // 暂时性死区
let a = 1
}
console.log(typeof a) // undefined
if(1) {
let a = 1
}
头大不?其实这个头(shuai)疼(qi)的名词解释的反而挺到位的。
var 不解释了,先解释第三个,就是常规的使用 typeof 检测变量属性,如果变量未申明,返回undefined,这是正常的;但是在 let 和 const(没错,const一样)所在作用域内,因为 let 和 const 的存在,导致其申明的变量被锁死,在申明前被调用的话,呵呵,不好意思,就算你是 typeof 大哥也没用,报错。
注意,说的是被 let 和 const 申明的才会被锁死,没被绑定的是常规处理,如下:
if(1) {
console.log(typeof jhdskfkjfhdkj) // undefined
console.log(typeof a) // 暂时性死区
let a = 1
}
与 window 的关系
没关系。
let RegExp = 1
window.RegExp // ƒ RegExp() { [native code] }
RegExp // 1
const
constant(跟我读:康斯顿~),就是不变的量,很多人容易忘记初始化,然后报错了再来添加初始值,这里脑子稍微过一下就可以记住:
假如不赋值能成功(说了假如),那就是 undefined,你没事创建个 undefined 来展示代码有多l ow 么?然后你又后面修改,但是本身人家就不能修改,所以一定需要初始化赋值,这样逻辑就通了……
恩,对了,他的作用域跟 let 一样一样的。没错,重复声明也不行。
之前说过,const 比较坑的就是,如果值是对象,对象的属性却是可以修改的……伪代码:
const a = {
b: 1
}
a = {} // 报错
a.b = 2 // 没错
暂时性死区
与 let 一样(const:喂喂喂,啥都跟 let 一样,搞得我好像它小弟一样。),但是由于 const 的不可变性,就不要想着用来搞常规循环那个啥了,这个跟 let 不一样。
常规循环就是 for(let i = 0; i < x.length; i ++) {}
这个,for in 和 for of 中 const 是可以用的,因为每次都是不同的嘛。
与 window 的关系
与那谁(let)一样。
用谁的问题
之前我文章写的是尽量使用 let,恩,现在我改了,这个真不是这个书的事情……
默认使用 const,除非是一定需要变动的,则使用 let,极特殊的情况下并且你能控制 var,再考虑使用 var。
欢迎关注,如有需要 Web,App,小程序,请留言联系。