前言
讲解var命令,let命令,const命令
一、var命令和let命令
var命令,let命令都是用来声明变量的。
1.var命令和let命令的声明
(1)声明一个变量的两种方式:
- 第一种(
var
):var num=1。如果在方法中声明,则为局部变量;如果在全局中声明,则为全局变量
- 第二种:num=1。事实上这是对属性进行赋值操作。首先,它会尝试在当前作用域链(如果在方法中声明,则当前作用域代表全局作用域和方法局部作用域)中解析num,如果在任何当前作用域链中找到num,则会对num属性进行赋值,如果没有找到num,他会在全局对象(即当前作用域链的最顶层对象,如window对象)中创造num属性并赋值
注意!它并不是声明了一个全局变量,而是创建了一个全局对象的属性
(2)ES6中增加了let,let
声明的变量只在let命令所在的代码块内有效。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>let和var命令</title> </head> <script> { var name = 'aa'; let age = 20; } console.log(name); //输出:aa console.log(age); //输出:(报错)age is not define //因为let只在声明的代码块中有效 </script> <body> </body> </html>
2.var命令和let命令的使用区别
- 变量提升。var命令会发生“变量提升”的现象,即变量可以在声明之前使用,值为undefined。这种现象多少有些奇怪,按照一般逻辑,变量应该在声明语句之后才能使用。为了纠正这种现象,let命令改变了雨打行为,所声明的变量一定要在声明后使用,否则报错。
//var情况 console.log(age); //输出undefined var age = 20; //let的情况 console.log(bar); //报错ReferenceError let bar = 2;
- 变量重复声明。var允许变量的重复声明,但是let命令不允许在相同作用域内,重复声明一个变量参数。
function func() { var a = 2; var a = 1; console.log(a);//对的,a=1; } func(); //报错 function func(){ let a= 10; var a= 1; } //报错 function func(){ let a= 10; let a=1; }
- let声明的参数也不可能与形参同名,如果声明的参数是在另一方作用域下,则是可以进行重复声明的。但是var均可。
function funb(arg) { { var arg; //不报错 } } function func(arg) { let arg; //报错:Identifier 'arg' has already been declared。因为两个arg参数不在同一个作用域内 } function funb(arg) { { let arg; //不报错,因为两个arg参数不在同一个作用域内 } }
- for循环中var变量和let变量的父子作用域的对比。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>for循环中的var和let父子作用域的对比</title> </head> <script> window.onload = function() { var myVar = document.getElementById('varCount'); var myLet = document.getElementById('letCount'); //输出10个10 for (var i = 0; i < 10; i++) { setTimeout(function() { myVar.innerHTML += i + ' '; }) } //输出0123456789 for (let j = 0; j < 10; j++) { setTimeout(function() { myLet.innerHTML += j + ' '; }) } } </script> <body> <div id="varCount">var变量循环:</div> <div id="letCount">let变量循环:</div> </body> </html>
在上述代码中,变量i是用var声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会变化,每次循环写入div标签内的都是全局变量i,通俗的理解就是这是此循环写入的都是i,但是这些i都是全局变量,即指向的都是同一个i,而i的值在变化,最后停止变化的值就是i的值。
而是用let声明的变量j,仅在块级作用域有效,所以每次循环填入标签内的j值都是一个新的变量。
二、const命令
- 用const命令声明的是一个只读的的常量,其值一旦声明就不能改变。这也意味着一旦声明常量就必须立即将其初始化,只声明不赋值会报错。
const PI=3.14;//正确 PI=3.1415926;//报错,因为PI已经被赋过值,不允许再有改动 const a;//报错,只声明未赋值
- const的作用域与let相同,只在声明所在的块级作用域内有效,且不可以重复声明。const,let均是先声明后使用。
- const命令实际保证的并不是变量的值不能动,而是变量指向的那个内存地址不能改动,对于简单类型的数据(数字,字符串,布尔值)而言,值就能保存在变量指向的内存地址中,但对于复合型数据类型(对象或数组)而言,变量指向的数据结构是不是可变的完全不可控制。
const obj={}; obj.name="john"; obj.age=20; //上诉代码没问题,向对象中输入属性值,可以对对象进行属性添加的操作 obj={};//报错,因为obj指向了另外一个对象 const names=[]; names.push("李四"); //上诉正确,把李四压入数组 name=["jane"];//报错,因为不能将另一个数组赋值给names常量数组
总结
上面就是对var,let,const命令的讲解。