我的NodeJs学习小结(一)

这第一篇就谈谈NodeJs的一些编程细节吧。

1、遍历数组

for (var i=0, l=arr.length; i<l; i++)

这样写的一个好处就是让每次循环少一步获取数组对象长度的操作,数组长度越长,价值越明显。

2、判断变量的真假

if (a) {...} //a='', a='0', a=[], a={}

if条件判断的结果分别是:false, true, true, true。这个结果和PHP的结果是不同的,不要混淆。还需要区分它和非恒等判断相似的情况。

3、0值非恒等判断

1 if (0 == '0') {...} //true
2 if (0 == []) {...} //true
3 if (0 == [0]) {...} //true
4 if (0 == {}) {...} //false
5 if (0 == null) {...} //false
6 if (0 == undefined) {...} //false

其实还有很多这种诡异的判断,我只列出了较为常见的。如果想弄明白其中的规则,请参阅我的另一篇博文:【JavaScript】深入分析JavaScript的关系运算和if语句。

4、parseInt的陷阱

var n = parseInt(s); //s='010'

该语句执行后n值为8,而不是10。虽然很多人知道这一点,但是编程中难免会出错,我深有体会。所以,最好按下面的方式来写,就不会出错了。

var n = parseInt(s, 10);

5、变量在使用前一定要先声明

虽然,直接使用变量而不声明也不会出错,但是,这样写是很容易出错的。因为解释器会把它解释成全局变量,很容易和其他全局变量重名而导致出错。所以,一定要养成变量使用前要先声明的好习惯。

6、循环中存在异步的情况

for (var i=0, l=arr.length; i<l; i++) {
   var sql = "select * from nx_user";
  db.query(sql, function(){
    sys.log(i + ': ' + sql);
  }); //db.query为表查询操作,是异步操作
}

你会发现,输出的结果都是相同的,而且是当i=arr.length-1时的输出内容。因为JavaScript是单线程的,它会先执行完整个循环的同步内容之后,才去执行其中的异步操作。代码中的匿名回调函数就是一个异步回调。执行到该函数的时候,for循环以及后面的一些同步操作都已经执行完毕。出于闭包原则,该函数会保留for循环的最后一次循环的sql变量和i变量的内容,所以才会导致错误的结果。

那怎么办呢?解决方法有两种,一种是使用立即函数,如下:

for (var i=0, l=arr.length; i<l; i++) {
  var sql = "select * from nx_user";
  (function(sql, i){
    db.query(sql, function(){
      sys.log(i + ': ' + sql);
    }); //db.query为表查询操作,是异步操作
  })(sql, i);
}

还有一种方法是将异步操作部分提取出来,单写一个函数,如下:

var outputSQL = function(sql, i){
   db.query(sql, function(){
      sys.log(i + ': ' + sql);
  }); //db.query为表查询操作,是异步操作
}

for (var i=0, l=arr.length; i<l; i++) {
  var sql = "select * from nx_user";
  outputSQL(sql, i);
}

7 、在对大量数据作处理时,尽量避免循环嵌套。

因为循环嵌套的处理时间会随着数据量的增加成指数级增长,所以应尽量避免。遇到这种情况,如果没有更好的办法,一般采取的策略是以空间换时间,即建立一张二级循环数据的Hash映射表。当然,还要具体情况具体分析。还有一点要说的是,某些方法本身就是一个循环体,如Array.sort()(该方法应该是用了两层循环实现),在使用的时候需加注意。

8、尽量避免递归调用。

递归调用的优点是代码简洁,实现简单,而它的缺点很重要,说明如下:

(1)函数栈的大小会随着递归层次成线性增长,而函数栈是有上限值的,当递归达到一定层数后函数栈就会溢出,从而导致程序出错;

(2)每递归一层都会增加额外的压栈和出栈操作,即函数调用过程中的保存现场和恢复现场。

所以,应尽量避免递归调用。

9、关于模块文件的作用域隔离。

Node在编译JavaScript模块文件的时候,已经对其内容进行了头尾包装,如下:

(function(exports, require, module, __filename, __dirname){
  你的JavaScript文件代码
});

从而使每个模块文件之间进行了作用域隔离。所以,当你编写NodeJs模块文件的时候,不需要自己再加一层作用域隔离封装了。如下面的代码格式,只会额外增加一层函数调用,是不推荐的:

(function(){
  ... ...
})();

10、数组和对象不要混用

下面是错误代码的示例:

var o = [];
o['name'] = 'LiMing';

数组和对象混用可能会导致不可预知的错误。我的一个同事就遇到过一个很奇怪的问题,先看代码:

var o = [];
o['name'] = 'LiMing';
var s = JSON.stringify(o);

他本以为对象o的name属性会在JSON串中,结果就是没有。当时我也很奇怪,但我有预感到是数组和对象混用的问题,试了一下,果然是它的问题。后来我在ECMA规范中查到,数组在序列化时是按JA规则进行的。所以,要养成一个好的编程习惯,正确使用数组和对象,不要混用。

11、promise优雅编程

相信接触过nodeJs的人都有过这样的体验,当异步回调里嵌套异步回调的时候,代码就显得很混乱,缺乏易读性。nodeJs的这一窘境可以借助promise来克服。promise就像一个雕琢器,让你的代码变得优雅、美观。promise有个A+规范,网上有几种实现方式,可以参阅。

(0)

相关推荐

  • 利用NodeJS和PhantomJS抓取网站页面信息以及网站截图

    利用PhantomJS做网页截图经济适用,但其API较少,做其他功能就比较吃力了.例如,其自带的Web Server Mongoose最高只能同时支持10个请求,指望他能独立成为一个服务是不怎么实际的.所以这里需要另一个语言来支撑服务,这里选用NodeJS来完成. 安装PhantomJS 首先,去PhantomJS官网下载对应平台的版本,或者下载源代码自行编译.然后将PhantomJS配置进环境变量,输入 $ phantomjs 如果有反应,那么就可以进行下一步了. 利用PhantomJS进行简

  • nodejs npm install全局安装和本地安装的区别

    npm的包安装分为本地安装(local).全局安装(global)两种,从敲的命令行来看,差别只是有没有-g而已,比如: 复制代码 代码如下: npm install grunt # 本地安装npm install -g grunt-cli # 全局安装 下面分别解释. 1. npm install xxx -g 时, 模块将被下载安装到[全局目录]中. [全局目录]通过 npm config set prefix "目录路径" 来设置. 通过 npm config get prefi

  • nodejs开发环境配置与使用

    先说下nodejs这个哦,有人以为它是一种语言,其实不是,它是一个平台,一个建立在google的V8引擎上的js运行平台,就是解析js,并提供自己 的一些API给用户调用.从目前的情况来看,这个发展情况还算好,明天都有好多的前端后台工程师在加入,连一些大神也在关注甚至写博客,昨晚我还看见一篇 文章写道一个外国的网站写了将近90搞nodejs的web插件,这个真牛啊!那学习中国东东对于我们来说最直接的能带来什么利益呢:前端人员由于熟悉 js那么可以基本简单学习下linux就可以上手了,那后台工程师

  • nodejs教程之环境安装及运行

    让nodeJS跑起来 第一步当然是安装nodeJS环境了,现在windows安装nodeJS比较快了,直接下载即可: http://www.nodejs.org/download/ 这里根据需要下载,下载完成后直接下一步下一步即可,完了我们就具有nodeJS环境了 第二步,为了方便我们后面操作,我们直接在D盘见了一个文件夹blog 然后打开windows命令行工具,进入d盘,输入: 复制代码 代码如下: express -e blog 然后里面可能有依赖包,我们需要进入blog目录安装(安装的配

  • nodejs教程之入门

    前言 再不学nodeJs,我们就老了......在HTML5大浪袭来的时候,很多先辈就开始了NodeJs之旅,而那时我还在做服务器端的程序 后来转成前端,和梯队的距离已经很大了,因为我会服务器端语言,还干了很久,所以至今才开始学习NodeJs,向完整的前端前进 这次学习NodeJs的计划是: ① 1-2周学习基础知识 ② 1周左右开发一个简单项目 ③ 利用NodeJs开发一套用于移动端调试的工具 ④ 打包相关(这个可能比较远了) NodeJs特点 ① 异步 从文件读取到网络请求,NodeJs皆以

  • nodejs文件操作模块FS(File System)常用函数简明总结

    件系统操作相关的函数挺多的.首先可以分为两大类. 一类是异步+回调的. 一类是同步的. 在这里只对异步的进行整理,同步的只需要在函数名称后面加上Sync即可 1. 首先是一类最常规的读写函数,函数名称和形式,应该是起源于C语言的. 复制代码 代码如下: fs.open(文件路径,读写标识,[文件mode值,666],回调函数(err,文件句柄fd));          fs.read(文件句柄fd,被写入的buffer,offset,length,position,回调函数(err, byte

  • nodejs npm包管理的配置方法及常用命令介绍

    1. 输入 npm config ls -l 可以查看当前的目录设置 复制代码 代码如下: ; cli configslong = true ; builtin config C:\Program Files (x86)\nodejs\node_modules\npm\npmrcprefix = "C:\\Users\\sam\\AppData\\Roaming\\npm" ; default valuesalways-auth = falsebrowser = "start

  • 使用Nodejs开发微信公众号后台服务实例

    摘要: 微信,庞大的用户基数,极强的用户粘性,在近两年吸引了无数的开发者注意力. Nodejs,近两年发展非常快的开发工具,尤其适合构建移动后台.本文就以笔者自己开发的实例,来描述如何基于Nodejs开发属于自己的微信公众号.在这个实例中,主要使用到了express, wechat, mongodb, monk等模块. 前期准备: 1.申请微信公众号,前往 https://mp.weixin.qq.com/  申请,这里不做过多阐述. 2. 购买服务器, 这里推荐Amazon的EC2,首次用户可

  • NodeJs基本语法和类型

    写在前面 今天想要查下Node的类型什么的知识,想要总结下,在Googol上看到一个文章,但是原始的链接不在了,在快照中把这篇文章拉出来,如果原作者有问题,请联系我! 该文章都是一些JS的基础,高手自动跳过!我之前没怎么写过js,这方面比较弱,所以在写node的时候也遇到了麻烦,这里给自己补充下知识! 正文 Node.js 的基础是 JavaScript 这门 脚本语言.而大多数的脚本语言一个共同的特点就是"弱类型". 不同于 PHP 的是,PHP 就是是有了新变量也无需申明,而 Ja

  • 抛弃Nginx使用nodejs做反向代理服务器

    时下不少场景,都是申请一个 VPS 主机来托管运行 Web 项目的,小弟我也不例外,购买了一个小型的 Win 03 VPS 使用着.在使用的过程中,面临一个问题,就是同一类型的服务端环境还好--但如果是一个 PHP.一个 ASP. 一个 JSP 的三种类型的服务端项目并存着,该怎么分配唯一的 80 端口呢?因为商业 WWW 网站的话,往往只能占用 80  端口,--当然,如果只是做服务的话,如接口之类的,使用其他端口就不会与 80 端口冲突了.许多开发者都会面临到 80 端口这个问题,并且实际情

  • nodejs的10个性能优化技巧

    下面是我们使用Node.js时遵循的10个性能规则: 1. 避免使用同步代码 在设计上,Node.js是单线程的.为了能让一个单线程处理许多并发的请求,你可以永远不要让线程等待阻塞,同步或长时间运行的操作.Node.js的一个显著特征是:它从上到下的设计和实现都是为了实现异步.这让它非常适合用于事件型程序. 不幸的是,还是有可能会发生同步/阻塞的调用.例如,许多文件系统操作同时拥有同步和异步的版本,比如writeFile和writeFileSync.即使你用代码来控制同步方法,但还是有可能不注意

随机推荐