JavaScript基本语法与变量声明

发布于:2022-12-15 ⋅ 阅读:(10729) ⋅ 点赞:(11)

目录

一、语法规范

 二、关键字和保留字

三、变量

 1.var 关键字定义变量

1.命名规范:

2.使用注意:

3.特点:

4.扩展 

 2.let关键字定义变量

1.特点:

 2.扩展:

三、const声明常量

 1.作用:

2.特点:

 3.const扩展

四、声明风格及最佳实践


一、语法规范

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
严格模式下保留
implements package public interface
protected static let private

模块代码中保留 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,且可以重复声明变量,并同时声明并赋值多个变量

 45cc833c8ff342a7ba2f21c766c7d3bf.png

(2)var声明提升

109f2e7c129d4129ad2ca6dd65899437.png

 JS代码解析是按照文档流文档流从上往下解析的,这里之所以不报错,是由于ECMAScript把它看成等价于如下代码

8a46a36f7f964c3f807908f172be2d93.png

(3)var声明作用域

全局变量:在全局作用域下的变量 在全局作用域下可以直接使用。

cc3fa79b670c4a51866b01790dab7308.png

局部变量:在局部作用域下的变量 只能在局部作用域中使用

eef0a8e42eae4d3386f27f565f94e3e4.png

 总结:只有在函数内用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)或者闭包

cc79ed312a0149ec927c1a18e3b2cc6a.png

(2)严格模式下不允许定义名为eval和arguments的变量 

 12cc195d32094f16a45a71685002223d.png

(3)在函数内定义var a=b=1,a为局部变量,b为全局变量 

   56edcbb7ad684b308b6f9554fa2e0a7b.png

 2.let关键字定义变量

let关键字的命名规范与var相同,这里只指出let关键字的特点与var关键字的不同之处以及一些相关扩展

1.特点:

(1)同一块中不允许重复声明,对于冗余报错不会因为混用let和var受影响:

81734d08acb547cf9e6a86e8fd29e9f6.png

5ccc1360a0c94738bf25d4e9b3f95098.png

(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)不存在变量提升:

 说起变量提升,这里需要提一嘴的是提升的是变量,但是变量的值不会被提升

 dd6a5476fcd54786a441ad2e4a87e930.png

 2.扩展:

(1)使用let在“全局作用域”中声明的变量不会成为window对象的属性(var声明的变量则会)20a905b0e8a8410f8016aed88710a283.png

 运行结果:

2127e63c85e846108d6eeef5b45c87b0.png

在局部作用域中则都不会成为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循环定义的迭代变量会渗透到循环体外部

331a5165fe4a42acbb0a8baeb13d4771.png

2.改成使用let之后,这个问题就消失了,因为迭代变量的作用域仅限于for循环体内部

ad45d714228b43e2b02e306948bc5083.png

3.在使用var的时候,最常见的问题就是对迭代变量的奇特声明和修改

 c228c18fb1bb41feb76db933e0880d28.png

之所以会这样,是因为在退出循环时,var定义的迭代变量保存的是导致退出循环的值

而在使用let声明迭代变量时,JavaScript引擎会在后台为每个迭代循环声明一个新的迭代变量,这样输出的就是我们期望的值

 476cab1bcede46c089d25283bd5ae627.png

三、const声明常量

 1.作用:

定义JS中的常量,且常量名通常大写(潜规则),以区分变量,例如

var pi=36;   //这是一个变量
const PI=3.14159;   //这是一个常量

2.特点:

1.声明同时必须初始化:

79a00265ae2546c6aa1e176ff9dba965.png

可以看到这个编译器会给我们报错 

 2.一经声明不允许修改

ee4145d4c6fc46fca58a4f022aa0c75e.png

编译器不会报错,那我们来看看运行结果

745afd2a48204cf68917d5643746109c.png 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