![Node.js开发实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/830/26793830/b_26793830.jpg)
3.1 JavaScript语法
JavaScript是一门直译式、弱类型的脚本语言,也是Web开发最重要的语言之一。JavaScript由ECMAScript、DOM(文档对象模型)、BOM(浏览器对象模型)三部分组成。ECMAScript规定了JavaScript的语法核心,这也是本节重点介绍的内容。
3.1.1 变量
1.交互式运行环境——REPL
Node.js提供了一个交互式运行环境——REPL。在这个交互式环境中可以运行简单的应用程序。在控制台直接输入node即可进入这个环境,此时控制台会显示一个“>”符号,表明我们已经进入这个环境,如图3.1所示。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P43_69776.jpg?sign=1739272664-RMCynuE5FbbmngZQBvHyxPgTUxf7B5QR-0-6e5b8d74eba5a6ed405161ff62a037c5)
图3.1 进入REPL运行环境
提示
如果要退出该运行环境,连续按两次Ctrl+C快捷键,或者输入.exit。Node.js的命令需要在前面加点。例如,可用.help查看所有命令。
本节中的所有代码都会在这个环境中使用和运行。
2.浏览器环境——Chrome
当然,读者也可以在浏览器的控制台运行。以Chrome浏览器为例,通过使用F12键或者Ctrl + Shift + I快捷键打开开发者工具,在开发者工具栏中选择Console面板,如图3.2所示。在Console中也是显示一个“>”符号,和REPL的使用方法一致。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P44_103051.jpg?sign=1739272664-0zn0e2xVjOyvPrIAjGCXo0aATyGa4O48-0-a7c47799a7b19af93d0d839c999c4a45)
图3.2 浏览器的Console面板
3.关键字var
JavaScript的变量通过关键字var来声明。前面说过JavaScript是一门弱类型的编程语言,JavaScript的所有数据类型都可以用var关键字来声明,通过var变量名=值的形式就可以对变量同时进行声明和赋值。和许多语言一样,JavaScript通过分号“;”来分隔不同的语句,以下这段代码就声明了两个变量:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P44_136368.jpg?sign=1739272664-2BBUOdbFx2oHMe1jH4nazRqAbsD3pN5H-0-dad974028847552553685d2626212011)
4.变量的命名
JavaScript规定变量名必须以字母、美元符($)、下划线(_)三者之一开头,同时JavaScript对大小写敏感,大小写不同也就意味着是不同的两个变量。同时,JavaScript不区分单引号与双引号,因此上一个例子与用单引号表示的效果一致:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P44_136370.jpg?sign=1739272664-njo2qGprk57tFLAJQjLE9GsGWRfPruz7-0-5cecea1374137c3888af9903a9005ff5)
5.变量提升机制
JavaScript中存在变量提升机制,也就是所有的变量声明在运行时都会提升到代码的最前方。例如,上个例子在运行时实际上会先声明两个变量再赋值:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P44_136372.jpg?sign=1739272664-BIMGq0Dq0C76W2MZocjOrilogAu1kwH7-0-00a18e25a2deb4b84e2b98ac79e853f3)
通过一个更直观的例子或许会让读者更易理解变量提升。在REPL中试图使用一个未声明的变量时会出现is not defined错误,如图3.3所示。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P45_103122.jpg?sign=1739272664-s5ZoG13bcZBxjN5nA3KlkQgOAeqk0rMy-0-44e6f3a36b8caa45b00617f4818fd172)
图3.3 变量未声明错误
如果试图使用一个已经声明却未赋值的变量,那么这个变量所代表的是undefined,如图3.4所示。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P45_103126.jpg?sign=1739272664-DtwzcnIjeJZYVLBkiWFCdEGZAO6gbx3s-0-f0097f5ce61f2c7b339c0512099e11db)
图3.4 已经声明却未赋值
提示
图3.4中有两行undefined:一个是白色,一个是半透明白色。执行node语句,在没有任何返回值的时候总是会输出一个undefined,读者不必介意,这不是错误。白色语句是正常输出的内容。
使用一个在后来定义赋值的代码时会返回undefined,如图3.5所示。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P45_103131.jpg?sign=1739272664-KyJKTNPWxBaJLdKps5gfrhNYRJ479jIC-0-7b68c19f6323e9b04f3f33783e914ddf)
图3.5 先使用后声明赋值
可以发现这段代码返回undefined正是因为变量提升,实际运行的代码如下:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P45_136374.jpg?sign=1739272664-BlV8ng3dZsvttXqjUYQXijnk3UHofk0r-0-0c9e2e351348ac00e3d0a9e6fa71dff4)
3.1.2 注释
JavaScript中的注释和很多其他编程语言类似,以双斜杠(//)代表单行注释,以“/*注释内容*/”形式代表多行注释。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P45_136376.jpg?sign=1739272664-olQ3OkTJPGQ3Gcc5KJovTq5c1pIHiD7q-0-b62b8812963c8ee5ea858e7d09b13718)
3.1.3 数据类型
JavaScript中的数据类型可以分为简单数据类型和复杂数据类型。简单数据类型有undefined、boolean、number、string、null,复杂数据类型只有object。object由一组无序的键值对组成。
1.利用typeof区分数据类型
利用操作符typeof可以部分区分以上数据类型。typeof返回的值有undefined、boolean、number、string、object和function。下面举一个例子。
【示例3-1】
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P46_136383.jpg?sign=1739272664-HQ5XBwRXP0hHJqoNPDdLM7egoFhEw4gH-0-50265984778ce2d58d79b6d5fb5c395a)
【代码解析】
可以看到null和object都返回了object,这是因为null实际上是一个空对象指针,当一个变量只声明未赋值时返回undefined。
number和string数据类型分别指数字类型和字符串类型;boolean类型和其他语言一样,仅有true和false两个值;null仅有一个值null。
2.利用Boolean()转化数据类型
JavaScript中可以利用Boolean()方法将其他数据类型转化为布尔值。需要注意的是,空字符串、0、null、undefined、NaN都将转化为false,其他值则会转化为true。下面举一个例子。
【示例3-2】
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P47_136389.jpg?sign=1739272664-2IqvDE5KUhY0HqTT53jyKvCZxcjuYOQZ-0-c0e574bd2d09f81bafe7a2c95e976bf3)
3.1.4 函数
在JavaScript中,声明一个函数只需要使用function关键字即可,如声明一个求和的函数,代码如下:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P47_136391.jpg?sign=1739272664-KBqPJ6OGglG6fIeIwXIbka9uBITBkwdK-0-661c33c57fcb376f136e1d800630d1a9)
当然,函数同样可以作为一个值传递给一个变量,例如:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P47_136393.jpg?sign=1739272664-HYPi4uadZeoJD6S50phtl4ve00Uld0Wz-0-969eb2ec634eae1db006da7219d3ae9d)
调用一个函数同样很简单,只需要在函数声明之后使用“函数名(参数)”的形式调用即可,如调用上面的函数:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P47_136395.jpg?sign=1739272664-2MQSnVHID8zLqEXZv6WNfTkLPctsPBEu-0-b4eafa3f44e0f73fee6f553935b84d8a)
函数中默认带有一个arguments对象,这是一个类数组对象。arguments记录了传递给函数的参数信息,因为javascript中的函数调用时,参数个数并不需要和定义函数时的个数一致。在上面的add()方法中多添加几个参数,函数仍然会正常执行,例如:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P48_136401.jpg?sign=1739272664-OhTmNyGR7sxQnbMGwncuvZ85NxTnTCQG-0-b29ef6c0d6e6925fe50702a09b8a93e1)
利用好这一点和arguments类数组特性可以对上述的add方法拓展一下,让这个函数无论接收多少个参数,总能返回这些数值的和:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P48_136402.jpg?sign=1739272664-t8T1NOU6HmUZf7TpulNf2y3Bp7flby6Z-0-eb78e77c75b8fcd980428a4d891f1fd6)
还可以利用JavaScript中的arguments类数组对象模拟函数重载。当然,实际上JavaScript并不支持函数重载,比如通过检测arguments对象的length属性做出不同的反应来模拟重载。下面给出一个完整的例子。
【示例3-3】
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P48_136403.jpg?sign=1739272664-saj8Nk791CtA234wJv8K7uU0h8uoC69r-0-29f9c254f1fa8a923d163ab37fc2963d)
以上代码的运行效果如图3.6所示。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P49_103762.jpg?sign=1739272664-O69CjbVzSuhUfyNXFfmuovUshF2UiVge-0-90a077a910e198798b21119b68c3b88e)
图3.6 运行效果
【代码解析】
arguments对象是一个类数组对象。通过数组的slice()方法可以把arguments对象转化为一个真正的数组,这样就可以使用数组的所有方法,而不用担心出现其他问题了。
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P49_136411.jpg?sign=1739272664-gECu5ISECYFXvWGpcLyDKovdl6MfN6tY-0-d0ff59fc91f94070bfbb9947ee3c1fc3)
3.1.5 闭包
JavaScript中的变量可以分为全局变量和局部变量。JavaScript中的函数自然可以读取到全局变量,而函数外部并不能读取到函数内部定义的变量,例如:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P49_136412.jpg?sign=1739272664-xN8QSURRl1QpST96NqW2OTL55AbphMha-0-4efdf06e5f392475a1a16666f5c0022c)
当然,这需要在定义变量的时候使用var关键字定义。不用var关键字定义的话,实际上这个变量会成为全局对象的一个属性。在Node.js中,全局对象是global,如果上面代码中的str2变量不使用var定义,str2就会成为一个全局变量,函数外部也是可以读取到这个变量的,例如:
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P50_136416.jpg?sign=1739272664-VfMto4CAAdpvW7aIcOybDzr7m6Xr3dLm-0-894be275dd40d447fa331c2f1b9c0e18)
提示
建议所有的变量都使用var关键字进行定义,以避免不必要的错误出现。
JavaScript中的闭包可以让函数读取到其他函数内部的变量,如下代码就可以让函数之外读取到函数内部定义的变量,这就是最简单的闭包。
【示例3-4】
![](https://epubservercos.yuewen.com/BE2223/15253389405244706/epubprivate/OEBPS/Images/Figure-P50_136418.jpg?sign=1739272664-oZEVXCw1hGcVlsKPcLuWrvpvqYqFDycQ-0-1861c1f690baabcba9228ed3a5f66c61)
以上就是JavaScript的简要介绍。更多关于JavaScript的知识,读者可以阅读相关的书籍进行学习和掌握。进行Node.js的学习之前,读者应该对JavaScript有一定的了解。