学习JavaScript数据结构与算法(第3版)
上QQ阅读APP看书,第一时间看更新

1.3.1 变量

变量保存的数据可以在需要时设置、更新或提取。赋给变量的值都有对应的类型。JavaScript的类型有数、字符串、布尔值、函数对象,还有undefined和null,以及数组、日期正则表达式

尽管JavaScript有多种变量类型,然而不同于C/C++、C#或Java,它并不是一种强类型语言。在强类型语言中,声明变量时需要指定变量的类型(例如,在Java中声明一个整型变量,要使用intnum = 1;)。在JavaScript中,我们只需要使用关键字var,而不必指定变量类型。因此,JavaScript不是强类型语言。然而,对于是否要将可选的静态类型(http://github.com/dslomov/typed-objects-es7)加入未来的JavaScript标准(ECMAScript),已经有了一些讨论以及一个处于草稿状态的标准。如果需要在写JavaScript时对变量设定类型,也可以使用TypeScript。我们会在本章稍后学习有关ECMAScript和TypeScript的内容。

下面的例子介绍如何在JavaScript里使用变量。

    var num = 1; // {1}
    num = 3; // {2}
    var price = 1.5; // {3}
    var myName = 'Packt'; // {4}
    var trueValue = true; // {5}
    var nullVar = null; // {6}
    var und; // {7}

❑ 在行{1},我们展示了如何声明一个JavaScript变量(声明了一个数值类型)。虽然关键字var不是必需的,但最好每次声明一个新变量时都加上。

❑ 在行{2},我们更新了已有变量。JavaScript不是强类型语言。这意味着你可以声明一个变量并初始化成一个数值类型的值,然后把它更新成字符串或者其他类型的值,不过这并不是一个好做法。

❑ 在行{3},我们又声明了一个数值类型的变量,不过这次是十进制浮点数。在行{4},声明了一个字符串;在行{5},声明了一个布尔值;在行{6},声明了一个null;在行{7},声明了undefined变量。null表示变量没有值,undefined表示变量已被声明,但尚未赋值。

如果想看声明的每个变量的值,可以使用console.log,如下所示。

    console.log('num: ' + num);
    console.log('myName: ' + myName);
    console.log('trueValue: ' + trueValue);console.log('price: ' + price);
    console.log('nullVar: ' + nullVar);
    console.log('und: ' + und);

console.log方法不只是接收这样的参数。除了console.log('num: ' + num),我们还可以使用console.log('num: ', num)的形式。第一种写法会将结果合并为一个字符串,而第二种写法则允许我们为其添加一个描述,并在变量为对象时将其内容以可视化的方式输出。

书中的示例代码会使用三种方式输出JavaScript的值。第一种是alert('My text here'),将输出到浏览器的警示窗口;第二种是console.log('My text here'),将把文本输出到调试工具(谷歌开发者工具或是Firebug,根据你使用的浏览器而定)的Console标签页;第三种是通过document.write('My text here')直接输出到HTML页面里并用浏览器呈现。可以选择你喜欢的方式来调试。

稍后会讨论函数和对象。

变量作用域

作用域是指,在编写的算法函数中,我们能访问变量(在使用函数作用域时,也可以是一个函数)的地方。有局部变量和全局变量两种。

让我们看一个例子。

    var myVariable = 'global';
    myOtherVariable = 'global';
    function myFunction() {
      var myVariable = 'local';
      return myVariable;
    }
    function myOtherFunction() {
      myOtherVariable = 'local';
      return myOtherVariable;
    }
    console.log(myVariable); // {1}
    console.log(myFunction()); // {2}
    console.log(myOtherVariable); // {3}
    console.log(myOtherFunction()); // {4}
    console.log(myOtherVariable); // {5}

上面的代码可解释如下。

❑ 行{1}输出global,因为它是一个全局变量。

❑ 行{2}输出local,因为myVariable是在myFunction函数中声明的局部变量,所以作用域仅在myFunction内。

❑ 行{3}输出global,因为我们引用了在第二行初始化了的全局变量myOtherVariable。

❑ 行{4}输出local。在myOtherFunction函数里,因为没有使用var关键字修饰,所以这里引用的是全局变量myOtherVariable并将它赋值为local。

❑ 因此,行{5}会输出local(因为在myOtherFunction里修改了myOtherVariable的值)。

你可能听其他人提过在JavaScript里应该尽量少用全局变量,这是对的。通常,代码质量可以用全局变量和函数的数量来考量(数量越多越糟)。因此,尽可能避免使用全局变量。