变量声明
var
先回忆一下es5的变量声明特性:
- 可以重复声明;
- 是函数级作用域;
- 有变量提升
- 在全局作用域中声明会直接加在window下
缺点:会带来定义混乱,误修改等问题。
1、4好理解为什么会带来上面说的缺点,2、3我举个例子:
// var a 变量提升
if (true) {
var a = 1
}
console.log(a)
能访问到a就是因为2、3的原因。
再来个同样道理的例子,关于循环的:
// var i
for (var i=0; i<10; i++) {
setTimeOut(()=>{
console.log(i)
}, 1000)
}
let
特点:
- 同一作用域不能重复声明;
- 有块级作用域;
- 在全局作用域中声明不会加在window下
下面例子:
// 同一个被let声明的变量不能重复被声明,除非在不同的块级作用域中,但这两个变量毫无关联。
{
let a = 123;
console.log(a);
}
{
let a = 321;
console.log(a);
}
// 想要修改只能在自己的作用域内=直接修改
for(let i =0; i<6; i++){
document.write(i);
}
console.log(i); //当声明变量的指令为var时,显示6;当为let时i得不到值;
// 所以块级可以理解为在{}里面有单独的变量
常量声明
const
常量相对于变量,可用全部大写来命名常量,便于与变量区分。
特点:
- 不能被重复声明,不能被重新赋值;
- 定义时必须赋值;
- 块级作用域;
- 是可修改的(因为我常记混,所以加入特点来巩固记忆);
- 在全局作用域中声明不会加在window下
关于let和const到底没有变量提升?不用纠结,表现上看是没有(实际上有),要是很想研究可以参考下:5行代码证明 let, const存在变量提升
三种声明形式怎么用
var已经被抛弃,定义变量优先使用const,写着写着发现定义的变量需要被修改,确定了再把cosnt改成let。
之前还有在网上看到有人有const声明时,常量名称喜欢用大写,个人建议正常驼峰写法即可,在那种全局的常量中再用大写。
运算符扩展
${} 模板字符串
在${}
中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
let name = '小米'
let num = 1999
let str = `${name}${num>1999 ? '太贵了' : '不忘初心'}`
模板字符串也支持换行写法(不是页面上那种换行)
… 运算符
这篇文章总结的很好es6之扩展运算符 三个点(…)
?. 可选链操作符
const name = obj && obj.name;
// 用?. 替代
const name = obj?.name;
当写模板的时候,要显示一个对象里的属性,但是这个对象后端有可能返回null,可以用这个处理:
<div>{{obj?.name || '无值'}}</div>
?? 空值合并操作符
当左侧的操作数为 null
或者 undefined
时,返回其右侧操作数,否则返回左侧操作数。
if(value !== null && value !== undefined && value !== ''){
//...
}
// 就可以换成
if((value??'') !== ''){
//...
}
注意事项
如果使用以上语法报错,就升级工程里的babel,至少7以上。
题外话
代码分号的问题,有些时候代码写分号是有必要的。例如
let str = ''
(aysnc function (){})()
因为str申明后面没有分号,js会把接下来的()符号当做是个执行命令,str(),就会直接报错,解决方法是加分号,或者在()加个!号做区分
let str = ''
!(aysnc function (){})()