Node.js知识

来源:互联网 发布:银行模拟教学软件 编辑:程序博客网 时间:2024/06/09 21:03
   Node.js最大的特点就是异步式I/O与事件紧密结合的编程模式。这种模式与传统的同步式I/O线性的编程思路有很大不同,因为控制流很大程度上要靠事件和回调函数来组织,一个逻辑要拆分为若干个单元。
1.console.log('%s:%d','Hello',25);
2.无论你修改了代码的哪一部分,都必须终止Node.js在重新运行才会奏效。这是因为Node.js只有在第一次引用到某部分时才会去解析脚本文件,以后都会直接访问内存,避免重复载入。 Node.js的这种设计虽然有利于提高性能,却不利于开发调试,因为我们在开发过程中总是希望修改后立即看到效果,而不是每次都要终止进程并重启。 supervisor可以帮助你实现这个功能,它会监视你对代码的改动,并自动重启Node.js.需要使用npm安装supervisor
$npm install -g supervisor
如涉及权限(Linux或Mac)sudo npm install -g supervisor命令来安装。
3.Node.js所有的异步I/O操作在完成时都会发送一个事件到事件队列。在开发者看来,事件由EventEmitter对象提供。在Node.js Libev支持多种类型的事件如ev_io、ev_signal、ev_i均被EventEmitter封装。libev事件循环的每一次迭代,在Node.js中就是一次 Tick,libev不断检查是否有活动的、可供检测的事件监听器,直到检测不到时才退出事件循环,进程结束。
Node.js知识

4.exports是模块公开的接口,require用于从外部获取一个模块的接口,即所获取模块的exports对象。
5.无论调用多少次require,获得的模块都是同一个。
//loadmodule.js
var hello1=require('./module');
hello1.setName('BYVoid');

var hello2=require('./module');
hello2.setName('BYVoid 2');

hello1.sayHello();
运行结果:  ByVoid 2
这是因为两个变量指向同一个实例,因此hello1.setName的结果被hello2.setName覆盖,最终输出的由后者决定。
6.若以exports.Hello=Hello生成模块接口

var Hello=require(./singleobject).Hello;
var hello=new Hello();
hello.setName('abc');
hello.sayHello();
若以module.exports=Hello生成模块接口
var Hello=require('./Hello');
var hello=new Hello();
hello.setName('abc');
hello.sayHello();
7.package.json,Node.js再调用某个包时,会首先检查包中package.json文件中的main字段,将其作为报的接口模块,如果 package.json或main字段不存在,会尝试寻找index.js或index.node作为包的接口。
一个完全符合CommonJS规范的package.json示例:
Node.js知识

8.使用 npm安装包的命令格式为:npm [install/i] [package_name]  例:npm install express  或 npm i express
9.命令行调试 node debug debug.js,将会启动调试工具,打开了一个Node.js的调试终端,用一些基本的命令进行单步跟踪调试。
Node.js知识
10.process是一个全局变量,即global对象的属性。它用于描述当前Node.js进程状态的对象,提供了一个与操作系统的简单接口。
process.argv
process.stdout是标准输出流,通常我们使用的console.log()向标准输出打印字符,而process.stdout.write()函数提供了更底层的接口。
process.stdin是标准输入流,初始时它是被暂停的,要想从标准输入读取数据,你必须恢复流,并手动编写流的事件响应函数。
process.stdin.resume();
process.stdin.on('data',function(data){
    process.stdin.write('read from console:'+data.toString());
});
process.nextTick(callback)的功能是为事件循环设置一项任务,Node.js会在下次事件循环调响应时调用callback。
process.stdin
11.util是Node.js核心模块,提供常用函数的集合,用于弥补核心JavaScript的功能过于精简的不足。    util.inherits(constructor,superConstructor)是一个实现对象间原型继承的数。
12.util.inspect(object,[showHidden],[depth],[ccolors])是一个将任意对象转换为字符串的方法,通常用于   调试和错误输出。它至少接收一个参数object,即要转换的对象。特别指出,util.inspect并不会简单地直接   把对象转换为字符串,即使该对象定义了toStirng()方法也不会调用。(还有util.isArray()、      util.isRegExp()、util.isDate()、util.isError()、util.format()、util.debug()等工具)
13.事件驱动events:events是Node.js最重要的模块,原因是Node.js本身架构就是事件式的,而它提供了唯一的接口。events模块只提供了一个对象:events.EventEmitter。EventEmitter的核心就是事件发射与事件监听器功能的封装。
EventEmitter.on(event,listener)为指定事件注册一个监听器。
EventEmitter.emit(event,[arg1],[arg2]...)发射event事件,传递若干可选参数到事件监听器的参数表。
EventEmitter.once(event,listener)为指定事件注册一个单次监听器,触发一次后立即解除该监听器。
EventEmitter.removeListener(event,listener)
EventEmitter.removeAllListener(event,listener)
14.http.ServerResponse是返回给客户端的信息,决定了用户最终能看到的结果。它是由http.Server的request事件发送的。
response.writeHead(statusCode,[headers]):向请求的客户端发送响应头。
response.write(data,[encoding]):向请求的客户端发送响应的内容。
response.end([data],[encoding]):结束响应,告知客户端所有发送已经完成。当所有要返回的内容发送完毕时,该函数必须被调用一次。如果不调用该函数,客户端将永远处于等待状态。
15.闭包:是函数式编程中的概念。JavaScript中的每个函数都是一个闭包。
var generateClosure=function()
{
      var count=0;
      var get=function()
      {
           count++;
           return count;
      };
      return get;
};
var counter=generateClosure();
console.log(counter());  //输出1
console.log(counter());  //输出2
console.log(counter());  //输出3
generateClosure()函数中有一个局部变量count,初值为0,还有一个叫做get的函数,get将其父作用域,也就是generateClosure()函数中的count变量增加1,并返回count的值。generateClosure()的返回值是get函数。在外部我们通过counter变量调用了generateClosure()函数并获取了它的返回值,也就是get函数,接下来反复调用几次counter(),每次返回的值都递增1。
16.使用对象初始化器创建对象。
var foo={
      'prop1':'bar',
      'prop2':'false',
      'prop3':function(){
                  return 'Hello World';
               }
};
构造函数:
function User(name,url)
{
        this.name=name;
        this.url=url;
        this.display=function(){
          console.log(this.name);        
}
var someuser=new User('byvoid','http://www.byvoid.com');然后就可以通过someuser来访问这个对象的属性和方法了。
}
17.call和apply:以不同的对象作为上下文来调用某个函数。简而言之,就是允许一个对象去调用另一个对象的成员函数。call可以用于实现对象的继承。call和apply的功能是一致的,两者的细微差别在于 call以参数表来接受被调用函数的参数,而apply以数组来接受被调用函数的参数。call和apply的语法分别是
func.call(thisArg[,arg1[, ...]])
func.apply(thisArg[,argsArray])其中func是函数的引用,thisArg是func被调用时的上下文对象,arg1、arg2或argsArray是传入func的参数。
var someuser={
name:'byvoid',
display:function(words)
{
      console.log(this.name+'says '+words);
}
var foo={
     name:'foobar'
};
someuser.display.call(foo,'hello');  //输出 foobar says hello
};
用Node.js运行这段代码,someuser.display是被调用的函数,他通过call将上下文改变为foo对象,因此在函数体内访问this.name时,实际上访问的是foo.name,因而输出了foobar。
18.bind:可以用call或apply改变被调用函数的上下文,但如果重复使用会不方便,因为每次都要把上下文对象作为参数传递,而且还会使代码变得不直观。针对这种情况,我们可以使用bind方法永久地绑定函数的上下文,使其无论被谁调用,上下文都是固定的。bind语法如下:
func.bind(thisArg[,arg1[,arg2[, ...]]]);
 例:
var someuser={
      name:'byvoid',
      func:function(){
         console.log(this.name);      
}
};
foo={
      name:'foobar'
};
foo.func=someuser.func;
foo.func();   //输出foobar

foo.func1=someuser.func.bind(someuser);
foo.func1();  // 输出byvoid

func=someuser.func.bind(foo);
func(); //输出foobar

func2-func;
func2(); //输出foobar
直接将foo.func赋值为someuser.func,调用foo.func()时,this指针为foo,所以输出结果是foobar。foo.func1使用了bind方法,将someuser 作为this指针绑定到someuser.func, 调用foo.func1()时,this指针为someuser,所以输出结果是byvoid。全局函数func同样使用了bind方法,将foo作为this指针绑定到someuser.func,调用func()时,this指针为foo,所以输出结果是foobar,而func2直接将绑定过的func赋值过来,与func行为完全相同。
19.原型:这样理解原型,原型就好像一件艺术品的原件,我们通过一台100%精确的机器把这个原件复制出很多份。
a.构造函数内定义的属性继承方式与原型不同,子对象需要显示调用父对象才能继承构造函数内定义的属性。
b.构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。
c.构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。
什么时候使用构造函数内定义来创建属性呢????
a. 除非必须使用构造函数闭包,否则尽量使用原型定义成员函数,因为这样可以减少开销。
b.尽量在构造函数内定义一般成员,尤其是对对象或数组,因为用原型定义的成员是多个实例共享的。
0 0
原创粉丝点击