以后碰到过一名后端小弟二话不说,参予后端两个vue3工程项目的机能与此同时实现。当机能顺利完成时小弟充分体现出他对vue3架构恰当的知觉,但轮到我看标识符时,科姬的var让我不由得无话可说。
“新闻稿表达式不是用var吗?“
“let和var不都是新闻稿表达式,你间接把var换成let不要是……”
坚信不而已那位小弟,也有许多老师在自学ES6的科学知识后,也是单纯指出let和const就而已替代了var的新用语。
表达式提高
ES6之前他们只学了varURL展开表达式的新闻稿,与此同时他们能备考下表达式提高的基本概念。
var新闻稿的表达式具备表达式提高的优点,在javascript的建立期操作过程中,会对新闻稿的表达式与表达式展开搜集,提高到返回值的顶端。
当中有三个技术细节:
1.多于新闻稿被提高(表达式会调用为undefined)
2.当表达式名和表达式名武装冲突时,表达式会被优先选择提高
具体内容看下表达式提高的效用:
console.log(num) // undefined
console.log(fun) // function fun(){…}
var num = 1
var fun = 2
function fun(){
// …
}
console.log(num) // 1
console.log(fun) // 2
一、let、const
1.let和const的具体内容使用
ES6新增了let和constURL:
let用于新闻稿表达式,用语与var类似const用于新闻稿常量:与表达式不同,常量是两个恒定的值,只读,不可修改常量在定义时必须展开调用赋值相同优点:在相同返回值内,无法对同两个表达式/常量展开重复新闻稿存在暂时性死区会形成块级返回值不会在全局新闻稿时(在最顶层返回值)创建window对象的属性他们通过标识符,观察以上的优点:
const新闻稿的常量无法被修改。let varData = variable;
const constData = constant;
varData = 1;
constData = true // Uncaught TypeError: Assignment to constant variable. const新闻稿时必须展开调用(let能不进行调用赋值)。let varData;
const constData; // Uncaught SyntaxError: Missing initializer in const declarationconst新闻稿的注意点:const而已限制表达式绑定的值,不会限制引用数据类型内部的变动。
const a = {
num : 1
}
a.num = 2 // 对象的属性仍然能被改动,不被影响a = 2 // 报错同一返回值内,无法对同两个表达式/常量展开重复新闻稿。let varData;
let varData = true; // Uncaught SyntaxError: Identifier varData has already been declaredconst constData = 1;
const constData = 2 //Uncaught SyntaxError: Identifier constData has already been declaredvar varData
let varData = 2 //Uncaught SyntaxError: Identifier varData has already been declared重复新闻稿的注意点:在switch语句中,因为let或const新闻稿会形成块级返回值,也会导致重复新闻稿。
switch (key) {
case 1:
let a = 1
break;
case 2:
let a = 2 //Identifier a has already been declaredbreak;
}2.暂时性死区
暂时性死区:Temporal dead zone——TDZ
先看一段标识符,方便他们对暂时性死区的理解:
console.log(a) // undefined
var a = 1
在js期时,他们学过预解析,var新闻稿的表达式会在初始化赋值前,展开表达式提高(hoisting),在展开标识符的执行期时,a表达式已经存在,且值为undefined
这种逻辑其实有些奇怪,他们对表达式a展开新闻稿和调用赋值,是为了后面的逻辑和机能,但在展开初始化赋值前,表达式a就已经能展开访问,并且有值。
ES6中为了纠正这种现象,改变语法行为:对let和const新闻稿的表达式/常量,一定要在新闻稿后使用,否则报错
console.log(a) // Uncaught ReferenceError: Cannot access a before initialization
let a = 1
在暂时性死区的基本概念中,let和const新闻稿的表达式/常量都规避了表达式提高(hoisting)优点带来的怪异逻辑,让后端程序员在编写标识符时,以更严谨的角度去展开编程,防止多余的误操作。
3.块级返回值
在ES6以后,多于全局返回值和表达式返回值,在ES6中,新增了块级返回值
块级返回值由一对大括号界定,在大括号内使用let和const展开新闻稿,才会形成块级返回值
{
let a = 1;
console.log(a) // 1
}
console.log(a) // a is not defined
让他们来看一下,块级返回值存在前后的对比:
if执行语句中,var新闻稿的表达式间接作用于if语句所在的返回值内。if(false){
var a = 1
}
console.log(a) // undefined能通过下面这个例子,更直观地观察:没有块级返回值带来的场景误读。var title = 1
function fun(){
if(title == undefined){
var title = 10
}
console.log(title) // 10
}
fun()fun表达式中,使用var新闻稿的title表达式因表达式提高(hoisting)优点,在执行前被提高到表达式返回值顶端,且初始值为undefined,当进入执行期时,if判断为true,进入if执行语句,展开title的赋值操作。这也是很多初学者一开始就会产生的疑问:
A:‘我明明是if判断成功,我才新闻稿这个表达式并调用,那在这一步操作以后,title不应该是沿着返回值链去寻找全局返回值中的title吗?‘。
B:‘表达式提高(hoisting)的优点’。
A:’那我肯定是要符合条件,才进入if执行语句,里面的标识符才会执行,title这个表达式才去调用和赋值。现在表达式提高不就导致了判断条件受到影响?。
B:‘表达式提高(hoisting)的优点’。
A: ……(按住自己的拳头)。
这个对话可能有些绕,他们能看图来解读这个老师的疑惑:
拥有块级返回值后,这段标识符的解读就不会出现误读的情景。var title = 1
function fun(){
if(title == undefined){
let title = 10
}
console.log(title) // 1
}
fun()for循环中var新闻稿的计数表达式间接作用于for语句所在的返回值内。function fun(){
for (var i = 0; i < 10; i++){
// …
}
console.log(i); // 10
}拥有块级返回值后,能避免用来计数的循环表达式泄露。function fun(){
for (let i = 0; i < 10; i++){
// …
}
console.log(i); // i is not defined
}异步标识符执行操作过程中,需要通过IIFE与此同时实现closure(闭包),达到打印目标。function fun(){
for (var i = 0; i < 10; i++){
;(function(i){
setTimeout(()=>{
console.log(i); // 0 1 2 3 …
})
})(i)
}
}拥有块级返回值后,不需要再通过closure(闭包)主动展开词法环境搜集。function fun(){
for (let i = 0; i < 10; i++){
setTimeout(()=>{
console.log(i); // 0 1 2 3 …
})
}
}总结
总结和介绍var、let和const的特点后,他们才能明白“间接将var换成let”这种做法携带的安全隐患有多大。
分析var和let/const的差别,必然要理清表达式提高(Hoisting)、暂时性死区(TDZ)和块级返回值(block)这几个基本概念分别产生的效用。
let、const也是为介绍决使用var时形成怪异逻辑的问题。通过规范的语法行为,统一标识符的恰当解读,减少标识符在编写及运行时的误操作,提高标识符的安全性和可读性。