变量定义:ECMAScript中的变量是命名的占位符,用于保存任意数据类型。目前有三种声明变量的方式:var、let、const。1.vardeclarationvarmessage;//通过var关键字后跟变量名来声明变量,可以保存任意类型的数据。在没有赋值的情况下,message的值为undefinedvarname='Jack'name=12//这里创建了一个名为name的变量,保存的是字符串类型的数据'Jack',只是一个简单的赋值。随后,不仅可以更改存储的值,还可以更改值的类型。1.var声明作用域注意:用var运算符定义的变量将成为包含它的函数的局部变量,不能在函数外调用。函数测试(){varmessage="hi";//局部变量}test();控制台日志(消息);//错误!//在函数内部使用var定义一个变量,意味着该变量在函数退出时会被Destroyed,无法在外部调用。功能测试(){消息=“嗨”;//全局变量}test();控制台日志(消息);//"hi"//去掉前面的var操作符后,message变成了一个全局变量,可以在函数外调用注意:在全局作用域中,var关键字创建的变量会为window对象添加相应的属性varname='jack'console.log(window.name)//'jack'2.var变量提升变量提升其实就是声明前的变量可以在当前作用域内使用,其值是undefined。console.log(name)//undefinedvarname='Tom'//在声明变量name之前使用了name变量,没有报错,但是undefinedfunctionfoo(){console.log(age);变种年龄=26;}foo();//undefined//同样在函数作用域中,也会有变量提升2.let声明let关键字创建变量的方法与var相同,不同的是let声明的作用域是块作用域,并且var声明的范围是函数范围。下面是let和var创建变量的区别1.let创建变量没有变量提升//varconsole.log(foo);//输出undefinedvarfoo=2;//让console.log(bar);//报错ReferenceErrorletbar=2;2.让会有一个暂时的死区。只要块级范围内有let命令,它声明的变量就会“绑定”(binding)这个区域,不再受外界影响。varnum=123;if(true){num='abc';//ReferenceErrorletnum;}//上面的代码中,有一个全局变量num,但是let在块级作用域中声明了一个局部变量num,导致下面或者绑定这个块级作用域,所以在let之前声明变量,给num赋值会报错。ES6明确规定,如果块中有let和const命令,则块为这些命令声明的变量从一开始就形成一个封闭的作用域。在声明之前使用这些变量将导致错误。简而言之,在代码块中,变量在使用let命令声明之前是不可用的。这在语法上称为“时间死区”(简称TDZ)。3.不要重复声明let不允许在同一个作用域内重复声明同一个变量。//错误函数func(){leta=10;vara=1;}//错误函数func(){leta=10;leta=1;}functionfunc(arg){letarg;}func()//错误函数func(arg){{letarg;}}func()//没有报错4.let会有块级作用域使用let在花括号{}内创建变量,而花括号{}会形成一个块级作用域。在块级作用域下创建的变量不能被外部使用,会报错。但是,通过var创建的变量没有块级作用域。如果(真){让年龄=26;控制台日志(年龄);//26}console.log(年龄);//ReferenceError:ageisnotdefinedif(true){varname='Matt';控制台日志(名称);//马特}console.log(name);//Matt块级作用域解决了以下两种情况:1.内部变量可能覆盖外部变量vartmp=newDate();functionf(){console.log(tmp);如果(假){vartmp='你好世界';}}F();//undefined2,用于计数的循环变量作为全局变量泄露vars='hello';for(vari=0;i
