我的NodeJs学习小结(一)


Posted in NodeJs onJuly 06, 2014

 这第一篇就谈谈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+规范,网上有几种实现方式,可以参阅。

NodeJs 相关文章推荐
Jquery通过ajax请求NodeJS返回json数据实例
Nov 08 NodeJs
nodejs的压缩文件模块archiver用法示例
Jan 18 NodeJs
Nodejs+Socket.io实现通讯实例代码
Feb 13 NodeJs
使用nodejs爬取前程无忧前端技能排行
May 06 NodeJs
nodejs 子进程正确的打开方式
Jul 03 NodeJs
nodejs操作mongodb的增删改查功能实例
Nov 09 NodeJs
nodejs实现简单的gulp打包
Dec 21 NodeJs
Linux Centos7.2下安装nodejs&amp;npm配置全局路径的教程
May 15 NodeJs
nodejs 使用http进行post或get请求的实例(携带cookie)
Jan 03 NodeJs
nodejs中使用worker_threads来创建新的线程的方法
Jan 22 NodeJs
NodeJS和浏览器中this关键字的不同之处
Mar 03 NodeJs
ubuntu系统下使用pm2设置nodejs开机自启动的方法
May 12 NodeJs
nodejs中使用monk访问mongodb
Jul 06 #NodeJs
nodejs之请求路由概述
Jul 05 #NodeJs
Nodejs中自定义事件实例
Jun 20 #NodeJs
Nodejs sublime text 3安装与配置
Jun 19 #NodeJs
nodejs实现黑名单中间件设计
Jun 17 #NodeJs
nodejs分页类代码分享
Jun 17 #NodeJs
nodejs npm包管理的配置方法及常用命令介绍
Jun 05 #NodeJs
You might like
php读取txt文件组成SQL并插入数据库的代码(原创自Zjmainstay)
2012/07/31 PHP
浅析php header 跳转
2013/06/17 PHP
推荐十款免费 WordPress 插件
2015/03/24 PHP
PHP中使用socket方式GET、POST数据实例
2015/04/02 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
2019/05/08 PHP
javascritp实现input输入框相关限制用法
2007/06/29 Javascript
js打印纸函数代码(递归)
2010/06/18 Javascript
jquery下异步提交表单 异步跨域提交表单
2010/11/17 Javascript
JS 如果改变span标签的是否隐藏属性
2011/10/06 Javascript
详解JS 比较两个Json对象的值是否相等的实例
2013/11/20 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
javascript实现全角与半角字符的转换
2015/01/07 Javascript
JavaScript错误处理
2015/02/03 Javascript
CSS图片响应式 垂直水平居中
2015/08/14 Javascript
开启Javascript中apply、call、bind的用法之旅模式
2015/10/28 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
angular中使用Socket.io实例代码
2017/06/03 Javascript
js实现前端图片上传即时预览功能
2017/08/02 Javascript
微信小程序 同步请求授权的详解
2017/08/04 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
重学JS之显示强制类型转换详解
2019/06/30 Javascript
小程序中手机号识别的示例
2020/12/14 Javascript
python进阶教程之文本文件的读取和写入
2014/08/29 Python
Python中模拟enum枚举类型的5种方法分享
2014/11/22 Python
Python进阶:生成器 懒人版本的迭代器详解
2019/06/29 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
什么是python的自省
2020/06/21 Python
python os.rename实例用法详解
2020/12/06 Python
数百万免费的图形资源:Freepik
2020/09/21 全球购物
建筑个人求职信范文
2014/01/25 职场文书
教师通用专业自荐书范文
2014/02/11 职场文书
小学雷锋月活动总结
2014/07/03 职场文书
小学生关于梦想的演讲稿
2014/08/22 职场文书
交通安全教育心得体会
2016/01/15 职场文书