注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Minary_Acdream

http://f10.moe/

 
 
 

日志

 
 

Node.js学习-第三章-Node中的JavaScript  

2014-06-08 01:05:20|  分类: node.js |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
前言
    本章介绍Node.js的核心扩展的相关内容。

global对象
    在浏览器中,全局对象指的就是window对象。在window对象定义的任何内容都可以被全局访问到。
    比如setTimeout其实就是window.setTimeout,document其实就是window.document。
    
    Node中有两个类似但却各自代表着不同含义的对象:
    1.global:和window一样,任何global对象上的属性都可以被全局访问到。
    2.process:所有全局执行上下文中的内容都在process对象中。在浏览器中只有一个window对象,在node中也只有一个process对象。举例来说,浏览器中窗口的名字是window.name,类似的,在Node进程中的名字是process.title。

实用的全局对象
    setTimeout,process.nextTick(),console.log, console.error等。

模块系统
    javascript语言标准中并未模块依赖以及模块独立定义专门的API。因此,导致了通过这种方式引入的多个模块会出现对全局命名空间的污染以及命名的冲突的问题。
    Node摒弃了采用定义一堆全局变量的方式,转而引入了一个简单但却强大无比的模块系统,该系统有三个核心全局对象:require,module,exports。

绝对和相对路径
    绝对模块指的是Node通过在其内部node_modules查找到的模块,或者Node内置的如fs这样的模块。
    已经安装了的模块,可以直接用require来引用,无需添加路径名。
    
    也可以使用相对路径:
    
    //module_a.js
    console.log('this is a');

    //module_b.js
    console.log('this is b');
    
    //main.js
    require('./module_a');
    require('./module_b');

运行node main即可以得到:
    this is a
    this is b

暴露API
    要让模块暴露一个成为require调用的返回值,就要依靠moduleexports和两个全局变量。

    在默认情况下,每个模块都会暴露出一个空对象。如果你想在该对象上添加属性,那么简单的使用exports即可。


// module_a.js
exports.name = 'join';
exports.data = 'this is some data';

var privateVariable = 6;

exports.getPrivate = function () {
    return privateVariable;
}

测试情况:
//index.js
var a = require('./module_a');
console.log(a.name);
console.log(a.data);
console.log(a.getPrivate());
    输出:
        join
        this is some data
        6
    

上述例子中,exports其实就是对module.exports的引用,骑在默认情况下是一个对象。
要是该对象上逐个添加属性无法满足你的需求,你还可以彻底重写module.exports。

//person.js
module.exports = Person;

function Person (name) {
    this.name = name;
};

Person.prototype.talk = function() {
    console.log('My name is 'this.name);
};
执行node index.js
//index.js
var Person = require('./person');
var john = new Person('john');
join.talk();
如上述例子所示,在index文件中,你不再是接受一个对象作为返回值,而是函数,这得归功于对module.exports的重写。

事件
    Node.js中基础API之一就是EventEmitter。无论在Node中还是在浏览器中,大量代码都依赖于所监听或者分发的事件:
    window.addEventListerner('load'function() {
        alter('窗口已加载');
    });
    

    浏览器中负责处理事件相关的DOM API只要包括addEventListener, removeEventListener以及dispatchEvent。它们还在用一系列从window到XMLHTTPRequest等其他的对象上。
    
    下述例子发起一个ajax请求,并通过监听stateChange事件来获知数据何时到达:
var ajax = new XMLHTTPRequest;
ajax.addEventListerner('stateChange'function(){
    if(ajax.readyState == 4 && ajax.responseText) {
        alter('Got some data: ' + ajax.responseText);
    }
});

ajax.open('GET''/my-page');
ajax.send(null);


在node暴露了Event EmiterAPI,该API 上定义了on,emit 以及 removerListener 方法。
它以process.EventEmitter形式暴露出来。
//eventEmitter/index.js
var EventEmitter = require ('event').EventEmitter;
var a = new EventEmitter;
a.on('event'function () {
    console.log('event called');
});
a.emit('event');

这个API相比DOM中的更加简洁,Node内部在使用,你也可以很容易的将其添加到自己的类中:
var EventEmitter = process.EventEmitter;
var MyClass = function() {};
MyClass.prototype.__proto__ = EventEmitter.prototype;

//这样,所有的MyClass的实例都具备了事件功能:

var a = new MyClass();
a.on('oneEvent'function(){
    //do something...
});

事件是Node非阻塞设计的重要体现。
Node通常不会直接返回数据(因为这样可能会在等待某个资源的时候发生线程阻塞),而是采用分发事件传递数据的方式。

再以HTTP服务器为例。当请求到达时,Node会调用一个回调函数,这个时候数据可能不会一下子都到达。POST请求(用户提交一个表单)就是这样的例子。

当用户提交表单时,通常会监听请求的data和end事件:
http.Server( function (req, res) {
    var buf = '';
    req.on ('data'function (data) {
        buf += data;
    });
    req.on ('end'function () {
        console.log('buf');
    });
});
这是Node.js中很常见的例子:将请求数据内容进行缓冲(data事件),等到所有数据都接收完毕后(end事件)再对数据进行处理。

事件是否会被触发,取决去实现它的API。
有些事件会触发error事件,有些事件只会触发一次,有些会被触发多次,有些API只会在特定情况下触发某种事件等等。

如果存在有这样的需求:不管某个事件在将来被触发多少次,都希望只调用一次回调函数:
a.once('某个事件'function () {
    //尽管事件触发多次,但次方法只会执行一次。
});
通常要弄清楚那些事件是可用的,需要查看模块的API文档。

buffer
除了模块之外,Node还弥补了语言的另一个不足, 那就是对二进制数据的处理。
buffer是一个表示固定内存分配的全局对象,就好比是一个由八位字节元素组成的数组,可以有效地在javascript中表示二进制数据。
该功能一部分作用就是可以对数据进行编码转换。比如可以创建一副用base64表示的图片,然后将其作为二进制PNG图片的形式写入到文件中。
 (注释:base64主要是一种仅用ASCII字符书写二进制数据的方式。换句话说,它可以让你用简单的英文字符来表示像图片这样的复杂事物,所以会占用更多的硬盘空间)
//buffers/index.js
var mybuffer = new Buffer('==iiij2i3h1li23h''base64');
console.log(mybuffer);
require('fs').writeFile('log.png', mybuffer);    //对于用console.log方法输出buffer对象而言,writeFile的确是个简单的接口,让原生字节数据生成图片。

运行该代码,并打开图片:
node index
open logo.png


  评论这张
 
阅读(106)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018