目录
一、语法规范
1.JavaScript严格区分大小写
2.标识符必须由字母、数字、下划线(_)和$组成,禁止以数字开头,使用驼峰大小写形式, 禁止与关键字冲突
3.分号可以作为语句结束的标志,也可以省略
4.注释:
单行注释://
多行注释:/* */
5.严格模式:一种不同的JavaScript解析和执行模型,在脚本开头加上“ use strict ”
<script>
"use strict";//在全局开启严格模式
function fun(){
"use strict";//在函数内开启严格模式
}
</script>
二、关键字和保留字
关键字:
ECMA-262 描述了一组具有特定用途的关键字,不能用作标识符或属性名。例如var const等
break | do | in | typeof | case | else |
instanceof | var | catch | export | new | void |
class | extends | return | while | const | finally |
super | with | continue | for | switch | yield |
debugger | function | this | default | if | throw |
delete | import | try |
保留字:
虽然没有规定特定用途,但他们是保留给将来做关键字用的。这些词汇不能用作标识符,但可以用作对象的属性名
始终保留 | enum | ||||||||
严格模式下保留 |
|
||||||||
模块代码中保留 | await |
三、变量
定义:可以保存任何数据类型的占位符,可以随时改变的量
1.var 关键字定义变量
1.命名规范:
- 变量名,常量名,函数名,方法名自定义,可以由数字,字母,下划线,$组成,禁止以数字开头
- 禁止与关键字冲突(var const function if else for while do break case switch return class)
- 变量名严格区分大小写
- 变量名尽量见名知意,多个单词组成采用小驼峰,例如:"userName"
2.使用注意:
- 变量如果省略 var 关键字,并且未赋值,直接访问会报错
- 变量使用 var 关键字声明但未赋值,变量初始值为 undefined
- 变量省略 var 关键字声明,已被赋值,可正常使用,影响变量作用域(下面会详细介绍)
3.特点:
(1)不初始化的情况下初始值为undefined,且可以重复声明变量,并同时声明并赋值多个变量
(2)var声明提升
JS代码解析是按照文档流文档流从上往下解析的,这里之所以不报错,是由于ECMAScript把它看成等价于如下代码
(3)var声明作用域
全局变量:在全局作用域下的变量 在全局作用域下可以直接使用。
局部变量:在局部作用域下的变量 只能在局部作用域中使用
总结:只有在函数内用var关键字定义的变量为局部变量,其余都是全局变量。在函数内部定义的全局变量只要调用一次,就会定义这个变量,并且调用后在函数外可以直接访问,而函数内局部变量在调用之后就会被销毁,所以函数外部无法访问到。不同域中的同名变量可以同时存在。
function abc(){
a=123; //这里省略var后a变成了全局变量
console.log(a);//123
}
abc();
console.log(a);//123
var a=123; //变量a为全局变量,全局作用域
console.log(a) //123
function abc(){
var a=456; //变量a为局部变量,局部作用域
console.log(a) //456
abc();
4.扩展
(1)在严格模式下,定义变量、常量不允许省略关键字。因此不建议在局部作用域中定义全局变量,这样的全局变量很难维护,有需求的话可以定义局部变量,在将这个局部变量返回(return)或者闭包
(2)严格模式下不允许定义名为eval和arguments的变量
(3)在函数内定义var a=b=1,a为局部变量,b为全局变量
2.let关键字定义变量
let关键字的命名规范与var相同,这里只指出let关键字的特点与var关键字的不同之处以及一些相关扩展
1.特点:
(1)同一块中不允许重复声明,对于冗余报错不会因为混用let和var受影响:
(2)Let声明范围是块作用域,而var是函数作用域,块作用域是函数作用域的子集,适用于var作用域的限制同样适用于let,简而言之,var与let的最大区别在于let在{}中是局部变量,而var在{}中是全局变量
if(1>0){
let a=1;
var b=2;
};
console.log(b);//2
console.log(a);//!报错
(3)不存在变量提升:
说起变量提升,这里需要提一嘴的是提升的是变量,但是变量的值不会被提升
2.扩展:
(1)使用let在“全局作用域”中声明的变量不会成为window对象的属性(var声明的变量则会)
运行结果:
在局部作用域中则都不会成为window对象属性
function abc(){
var a=123; //a是局部变量
let b=456; //b是局部变量
const c=3.14159 //c是局部变量
console.log(window.a); //undefined
console.log(window.b); //undefined
console.log(window.pi); //undefined
}
abc();
console.log(window.a); //undefined
console.log(window.b); //undefined
console.log(window.pi); //undefined
console.log(window.s1); //undefined
//表明任何局部变量都不会成为window对象
不知道大家有没有发现这里有一个问题,函数内定义的局部变量此时可以在函数外输出undefined,很容易误导我们此时的变量是否被提升到函数外面,在我们调用window方法时,会和typeof方法一样,对于没有定义的变量都会输出默认值
function abc(){
//
var a=123; //a是局部变量
let b=456; //b是局部变量
const c=3.14159 //c是局部变量
console.log(window.a); //undefined
console.log(window.b); //undefined
console.log(window.pi); //undefined
}
abc();//函数在这里调用时会将里面的变量提升到函数顶部,但是值不会提升
console.log(window.a); //undefined
console.log(window.b); //undefined
console.log(window.pi); //undefined
//解析:任何局部变量都只会被提升到函数顶部,并非全局作用域,通过变量b也可以看出,因为let
//声明的变量不存在变量提升
(2) let这个新的ES6声明关键字,不能依赖与条件声明模式:
关于这个问题,个人觉得就是let提升的问题就是不同块中可以重复声明,条件声明模式是一种反模式,他会让程序变得更难理解,不能使用let进行条件声明或许是件好事。想深入了解的小伙伴可以去查阅相关资料,这里不再做详细介绍
(3)for循环中的let声明
1.在let出现之前,for循环定义的迭代变量会渗透到循环体外部
2.改成使用let之后,这个问题就消失了,因为迭代变量的作用域仅限于for循环体内部
3.在使用var的时候,最常见的问题就是对迭代变量的奇特声明和修改
之所以会这样,是因为在退出循环时,var定义的迭代变量保存的是导致退出循环的值
而在使用let声明迭代变量时,JavaScript引擎会在后台为每个迭代循环声明一个新的迭代变量,这样输出的就是我们期望的值
三、const声明常量
1.作用:
定义JS中的常量,且常量名通常大写(潜规则),以区分变量,例如
var pi=36; //这是一个变量
const PI=3.14159; //这是一个常量
2.特点:
1.声明同时必须初始化:
可以看到这个编译器会给我们报错
2.一经声明不允许修改
编译器不会报错,那我们来看看运行结果
3.不允许重复声明
const PI=3.14159
const PI=666 //编译器报错
4.const声明的作用域也是块
if(true){
const PI=3.14159
}
console.log(PI) //PI没有定义
3.const扩展
1.const声明的限制只适用于它指向的变量的引用,换句话说,如果const变量引用的是一个对象,那么修改这个对象的内部属性不违反const的不可修改限制
const PI={};
console.log(PI); //输出{}
console.log(typeof PI) //object
PI.name='小明'; //ok
PI.age=18; //pk
console.log(PI); //输出{name: '小明', age: 18}
2.不允许用const来声明迭代变量,因为迭代变量会自增或自减,违反了const的限制
<script>
for(const a=0;a<5;a++)
{
console.log(a) //!报错
}
</script>
四、声明风格及最佳实践
关于三种声明办法,哪一种方法最合适?最后做一点总结
1.不使用var:
有了let和const,变量有了明确的作用域、声明位置、以及不变的值,也就不在必要使用var,这样有助于提升我们的代码质量
2.const优先,let次之:
只有在提前知道未来会有修改时,才使用let