变量代表了内存中存储数据的位置。直观地说,它们就是一堆我们可以放入数据的盒子的名字。
要使用变量,我们需要先声明一个变量,然后再为其附上数据。
在Javascript中,变量的声明可以用关键字var
、let
和const
。
ES6语言标准里新引入了let
和const
关键字,但是在2015年之前,var
是变量声明的唯一选择。在本文中,我们将专门讨论var
。
var
关键字var
在Javascript中声明函数作用域或全局作用域变量。undefined
值初始化。JavaScript变量的命名规范:变量名称只能包含字母,数字或符号$和_,并且第一个字符不得为数字。
下面例子里,分别用var声明了三个分别是数值、字符串和函数类型的对象:
var x = 5; console.log('value of x is: ', x); // value of x is: 5 var str = "I am a string"; console.log(str); // I am a string var myFunction = function() { console.log('hey'); } console.log(myFunction); // ƒ () {console.log('hey');}
var
可以声明函数作用域(function-scoped)或全局作用域(globally-scoped)变量,但无法创建块作用域。
全局作用域
var value = 10; function logger() { console.log(value); //10 } console.log(value); //10
该value
变量位于全局作用域内,因此我们可以在该范围内的任何位置访问该变量,无论它在函数内部还是在10000行之后。
函数作用域
function mood() { var happy = true; console.log(happy); // true } console.log(happy); // ReferenceError: happy is not defined
该value
变量是在函数作用域内的话,我们只能在函数内部访问它,而不能在函数外面访问。如果在函数外面访问,会产生一个引用错误。
块作用域
var a = 2; if (a > 1) { var name = '乐码范'; } function logger() { console.log(name); } logger(); // 乐码范 console.log(name); // 乐码范
在这里,name
变量不会创建块作用域,而是像全局作用域中的变量一样随处可见。因此,如果无法实现块作用域,则无法声明任何私有变量。
在2015年之前,使用var是声明变量的唯一选择,然后要获取块作用域时,我们可以使用IIFE模式。
IIFE(Immediately invoked function expressions):立即调用的函数表达式。它描述了可以立即调用的函数表达式,它具有自己的私有变量。例如:
(function() { var greeting = "你好,乐码范的用户!"; console.log(greeting); // 你好,乐码范的用户! })();
在此语法中,将块代码用函数包括起来,然后立即使用()
来调用函数。
然后,我们再用这个方式改造一下前面的代码:
var a = 2; (function() { if (a > 1) { var name = '乐码范'; } })(); console.log(name); // ReferenceError: name is not defined
用var
可以对变量再次声明和初始化,这不会引起JavaScript的任何错误。
var name = '乐码范'; var name = 'lema.fun'; console.log(name); // lema.fun
在执行任何代码之前,先处理变量声明。因此,在代码中的任何位置声明变量等同于在顶部声明变量。此行为称为“提升”,因为似乎变量声明移到了范围的顶部:函数或全局。
test = 10; var test; console.log(test); // 10
使用var
,我们可以先给变量赋值,然后再声明该变量。这不会引发JavaScript的错误。这里有三个步骤:
var
声明的变量被提升;undefined
;test = 10
,则将更新后的值分配给该变量。注意:声明是提升的,但赋值不提升。例如:
console.log(name); // undefined // 这里有一些代码 name = "乐码范"; console.log(name); // 乐码范 // 这里有一些代码 var name;
变量name
由于提升,该变量在第一个console
之前被处理,但只有声明而不是赋值被提升。因此,其值最初是undefined
。就像将undefined
分配给name
变量一样。在执行中完成实际赋值之后,会将值“乐码范”分配给name
变量。