node基础知识

Node.js 是3个基于 Chrome V8 引擎的
JavaScript 运营环境,是叁个得以让 JavaScript 运转在服务器端的平台

Node.js 使用了二个事件驱动、非阻塞式 I/O 的模子,使其轻量又高效。Node.js
的包管理器 npm,是天下最大的开源库生态系统。

动用了单线程、异步式I/O、事件驱动式的主次设计模型

I/O(input/output),即输入/输出端口。每一种设备都会有2个专用的I/O地址,用来处理本人的输入输出音信。

ctrl + c – 退出当前极端。

ctrl + c 按下五遍 – 退出 Node REPL。

ctrl + d – 退出 Node REPL.

向上/向下 键 – 查看输入的野史命令

tab  – 列出当前命令

help – 列出利用命令

break – 退出多行表明式

.clear – 退出多行表达式

save filename – 保存当前的 Node REPL 会话到钦赐文件

load filename – 载入当前 Node REPL 会话的文件内容。

 

Node.js 事件循环

Node.js
是单进度单线程应用程序,然则透过事件和回调补助并发,所以品质非凡高。

Node.js 的每三个 API
都以异步的,并作为3个独立线程运营,使用异步函数调用,并处理并发。

Node.js 基本上全部的事件机制都以用设计格局中观看者形式实现。

Node.js
单线程类似进入2个while(true)的事件循环,直到没有事件观看者退出,每个异步事件都生成1个轩然大波观看者,如若有事件发生就调用该回调函数.

 

观察者格局:观察者方式定义了一种一对多的信赖关系,让多个观望者对象同时监听某三个宗旨对象。那几个宗旨对象在气象发生变化时,会打招呼全数观望者对象,使它们能够自动更新本人。

 

事件驱动程序

Node.js 使用事件驱动模型,当web
server接收到请求,就把它倒闭然后进行处理,然后去服务下一个web请求。

当那些请求完成,它被放回处理队列,当到达队列发轫,那几个结果被重回给用户。

那个模型格外高效可增加性格外强,因为webserver一直接受请求而不等待别的读写操作。(那也被称之为非阻塞式IO恐怕事件驱动IO)

在事件驱动模型中,会转移一个主循环来监听事件,当检查和测试到事件时触发回调函数。

 

 

全部事件驱动的流程正是那样达成的,至极简洁。有点类似于观望者情势,事件相当于多个核心(Subject),而享有注册到这么些事件上的处理函数也就是观望者(Observer)。

Node.js 有八个放置的轩然大波,大家能够通过引入 events 模块,并经超过实际例化
伊芙ntEmitter 类来绑定和监听事件

 

 

Node.js 中所谓的 JavaScript 只是 Core JavaScript,可能说是 ECMAScript
的一个落到实处,不分包 DOM(文书档案对象模型)、BOM(浏览器对象模型) 或然Client JavaScript(客户端脚本)。那是因为 Node.js
不运转在浏览器中,所以不要求选取浏览器中的许多表征。

 

Node.js 能做哪些

有着复杂逻辑的网站;

基于社交网络的常见 Web 应用;

Web Socket 服务器;

TCP/UDP 套接字应用程序;

命令行工具;

交互式终端程序;

含有图形用户界面包车型客车当地应用程序;

单元测试工具;

客户端 JavaScript 编译器。

 

TCP/UDP协议

TCP (Transmission Control Protocol)和UDP(User Datagram
Protocol)协议属于传输层协和式飞机。在那之中TCP提供IP环境下的数码有限支撑传输,它提供的服务包涵数据流传送、可相信性、有效流控、全双工操作和多路复用。通过面向连接、端到端和保障的数据包出殡。通俗说,它是优先为所发送的数码开辟出连接好的大路,然后再实行数量发送;而UDP则不为IP提供可信性、流控或差错复苏功效。一般的话,TCP对应的是可信性要求高的选取,而UDP对应的则是可信赖性供给低、传输经济的施用。TCP扶助的施用协议首要有:Telnet、FTP、SMTP等;UDP帮助的应用层情商首要有:NFS(互联网文件系统)、SNMP(简单网络管理协议)、DNS(主域名称系统)、TFTP(通用文件传输协议)等。

 

Node.js 用异步式 I/O 和事件驱动代替四线程,带来了中度的性质进步。Node.js
除了运用 V8 作为JavaScript引擎以外,还动用了快速的 libev 和 libeio
库帮助事件驱动和异步式 I/O。

 

 

 

CommonJS 为了统一javascript在浏览器外的贯彻

CommonJS
规范包蕴了模块(modules)、包(packages)、系统(system)、二进制(binary)、控制台(console)、编码(encodings)、文件系统(filesystems)、套接字(sockets)、单元测试(unit
testing)等片段。近期多数正经都在拟定和座谈之中,已经发布的标准有

Modules/1.0、Modules/1.1、Modules/1.1.1、Packages/1.0、System/1.0。

 

REPL (Read-eval-print loop),即输入—求值—输出循环

例子:

$ node

> console.log(‘Hello World’);

Hello World

Undefined

 

Supervisor工具

在支付 Node.js 达成的 HTTP
应用时会发现,无论你改改了代码的哪一部份,都必须下马

Node.js 再另行运转才会卓有成效。那是因为 Node.js
只有在首先次引用到有个别份时才会去分析脚本文件,以往都会直接待上访问内部存款和储蓄器,制止再一次载入,

Node.js的那种安插即便有利于升高品质,却不便于开发调节和测试,因

为大家在开发进程中年老年是希望修改后马上看到效能,而不是每便都要停下进度同等对待启。

supervisor 能够扶助您兑现那么些意义,它会监视你对代码的改变,并自动重启
Node.js。

选择方式不会细小略,首先使用 npm 安装 supervisor:

$ npm install -g supervisor

假定您使用的是 Linux 或
Mac,直接键入上边的命令很只怕会有权力错误。原因是 npm供给把 supervisor
安装到系统目录,供给管理员授权,能够利用  sudo npm install -gsupervisor
命令来设置。

接下去,使用 supervisor 命令运行 app.js:

$ supervisor app.js

 

异步式 I/O 与事件式编制程序

Node.js 最大的特征正是异步式 I/O(或许非阻塞
I/O)与事件紧凑结合的编程形式。那种形式与历史观的同步式 I/O
线性的编制程序思路有相当的大的两样,因为控制流非常大程度上要靠事件和回调函数来公司,一个逻辑要拆分为多少个单元。

堵塞与线程

什么是阻塞(block)呢?线程在履行中一经遇到磁盘读写或网络通讯(统称为
I/O 操作),常常要成本较长的时间,那时操作系统会剥夺这一个线程的 CPU
控制权,使其暂停实施,同时将财富让给其余的做事线程,那种线程调度形式叫做
阻塞。当 I/O
操作甘休时,操作系统将这几个线程的阻塞状态解除,恢复生机其对CPU的控制权,令其继续执行。这种
I/O 方式便是经常的同步式 I/O(Synchronous I/O)或阻塞式 I/O (Blocking
I/O)。

对应地,异步式 I/O (Asynchronous I/O)或非阻塞式 I/O (Non-blocking
I/O)则针对全体 I/O 操作不使用阻塞的方针。当线程遭受 I/O
操作时,不会以堵塞的方法等待 I/O 操作的姣好或数额的归来,而只是将 I/O
请求发送给操作系统,继续执行下一条语句。当操作系统达成 I/O
操作时,以事件的样式文告执行 I/O
操作的线程,线程会在一定时候处理这些事件。为了处理异步
I/O,线程必须有事件循环,不断地检讨有没有未处理的事件,依次授予拍卖。

堵塞模式下,三个线程只好处理一项职分,要想提升吞吐量必须通过二十八线程。而非阻塞格局下,三个线程永远在实施总括操作,那个线程所运用的
CPU 核心利用率永远是 百分之百,I/O
以事件的法子通报。在堵塞格局下,四线程往往能升高系统吞吐量,因为叁个线程阻塞时还有此外线程在办事,十二线程能够让
CPU 财富不被封堵中的线程浪费。而在非阻塞方式下,线程不会被 I/O
阻塞,永远在使用 CPU。十六线程带来的补益仅仅是在多核 CPU
的情状下行使越来越多的核,而Node.js的单线程也能带动一样的益处。那即是为什么Node.js 使用了单线程、非阻塞的风浪编制程序方式

 

单线程事件驱动的异步式 I/O 比古板的三十二线程阻塞式 I/O
终归幸亏哪个地方吧?简单的讲,异步式 I/O
正是少了多线程的开发。对操作系统来说,创制贰个线程的代价是老大高昂的,需求给它分配内部存款和储蓄器、列入调度,同时在线程切换的时候还要执行内存换页,CPU
的缓存被清空,切换回来的时候还要再度从内部存款和储蓄器中读取音讯,破坏了数量的区域性。

 

 

回调函数

Node.js 中怎样用异步的方法读取一个文件

//readfile.js

var fs = require(‘fs’);

fs.readFile(‘file.txt’, ‘utf-8’, function(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

});

console.log(‘end.’);

运作的结果如下:

end.

Contents of the file.

 

注:function()是回调函数,在Node.js 中,异步式 I/O
是透过回调函数来达成的。 fs.readFile 
接收了多个参数,第一个是文件名,第一个是编码格局,第5个是3个函数,我们称那个函数为回调函数。

JavaScript
协理匿名的函数定义格局,譬如大家例子中回调函数的概念正是嵌套在fs.readFile 
的参数表中的。那种概念方式在 JavaScript 程序中颇为广阔,与下部这种概念

办法贯彻的效果是同样的:

//readfilecallback.js

function readFileCallBack(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

}

var fs = require(‘fs’);

fs.readFile(‘file.txt’, ‘utf-8’, readFileCallBack);

console.log(‘end.’);

fs.readFile  调用时所做的做事只是将异步式 I/O
请求发送给了操作系统,然后随即重回并履行后边的话语,执行完今后进入事件循环监听事件。当
fs  接收到 I/O
请求完结的风云时,事件循环会主动调用回调函数以形成后续工作。因而大家会先来看
end. ,再收看file.txt 文件的剧情

 

事件

Node.js 全体的异步 I/O
操作在完毕时都会发送1个风云到事件队列。在开发者看来,事件由
伊夫ntEmitter  对象提供。

 

Node.js 的事件循环机制

Node.js 在怎么着时候会跻身事件循环呢?答案是 Node.js
程序由事件循环起初,到事件循环截至,全体的逻辑都是事件的回调函数,所以
Node.js
始终在事件循环中,程序入口正是事件循环第③个事件的回调函数。事件的回调函数在履行的进度中,大概会产生I/O
请求或直接发射(emit)事件,执行完成后再回去事件循环,事件循环会检查事件队列中有没有未处理的事件,直到程序结束。

 

 

模块和包

怎么是模块

模块是 Node.js
应用程序的为主组成都部队分,文件和模块是逐一对应的。换言之,一个Node.js
文件正是2个模块,那一个文件大概是 JavaScript 代码、JSON 只怕编写翻译过的
C/C++ 扩大。

 

在头里章节的例子中,大家早已采纳了  var http = require(‘http’), 当中http是 Node.js 的一个中央模块,其里面是用 C++ 完成的,外部用 JavaScript
封装。大家经过require 函数获取了那么些模块,然后才能利用个中的对象。

 

创立及加载模块

1. 成立模块

三个文件正是3个模块

Node.js 提供了 exports 和  require  多个对象,当中  exports
是模块公开的接口, require 用于从表面获得2个模块的接口,即所收获模块的 
exports 对象。

 

例子:

//module.js

var name;

exports.setName = function(thyName) {

name = thyName;

};

exports.sayHello = function() {

console.log(‘Hello ‘ + name);

};

 

在同样目录下创制 getmodule.js,内容是:

//getmodule.js

var myModule = require(‘./module’);

myModule.setName(‘BYVoid’);

myModule.sayHello();

运行node getmodule.js,结果是:

Hello BYVoid

 

在上述示例中,module.js 通过  exports 对象把 setName  和  sayHello
作为模块的走访接口,在 getmodule.js 中经过  require(‘./module’)
加载那个模块,然后就能够直接待上访问 module.js 中  exports
对象的成员函数了。

 

2. 单次加载

上面那一个事例有点类似于成立二个指标,但事实上和指标又有实质的区分,因为

require 不会再一次加载模块,也正是说无论调用多少次  require,
获得的模块都是同三个。

作者们在 getmodule.js 的根基上稍作修改:

//loadmodule.js

var hello1 = require(‘./module’);

hello1.setName(‘BYVoid’);

var hello2 = require(‘./module’);

hello2.setName(‘BYVoid 2’);

hello1.sayHello();

运作后意识输出结果是  Hello BYVoid 2 ,那是因为变量  hello1 和hello2
指向的是同三个实例,由此  hello1.setName 的结果被 hello2.setName
覆盖,最后输出结果是由后者决定的。

 

3. 覆盖  exports

把一个对象封装到模块中,例如:

//singleobject.js

function Hello() {

var name;

this.setName = function (thyName) {

name = thyName;

};

this.sayHello = function () {

console.log(‘Hello ‘ + name);

};

};

exports.Hello = Hello;

那会儿我们在其他文件中要求通过 require(‘./singleobject’).Hello 
来取得Hello  对象,那略显冗余,能够用上面方法稍微简化:

//hello.js

 

function Hello() {

var name;

this.setName = function (thyName) {

name = thyName;

};

this.sayHello = function () {

console.log(‘Hello ‘ + name);

};

};

module.exports = Hello;

//gethello.js

var Hello = require(‘./hello’);

hello = new Hello();

hello.setName(‘BYVoid’);

hello.sayHello()

 

留意,模块接口的绝无仅有变化是接纳  module.exports = Hello 代替了 
exports.Hello=Hello 。在表面引用该模块时,其接口对象便是要出口的  Hello
对象自小编,而不是本来的exports 。

实则, exports  本人只是是1个一般性的空对象,即 {}
,它特别用来声称接口,本质上是因此它为模块闭包的个中建立了1个点滴的访问接口。因为它从不其余极度的地点,所以可以用其它东西来代表,譬如大家地方例子中的
Hello  对象。

 

警告:

不得以由此对exports 直接赋值代替对module.exports 赋值。

exports 实际上只是叁个和  module.exports
指向同三个对象的变量,它本人会在模块执行完结后刑释,但
module不会,由此不得不通过点名module.exports 来改变访问接口。

 

创建包

包是在模块基础上更深一步的悬空,Node.js 的包类似于 C/C++ 的函数库可能Java/.Net的类库。它将某些独立的遵守封装起来,用于发表、更新、依赖管理和版本控制。Node.js
依照 CommonJS 规范落到实处了包机制,开发了 npm来缓解包的发表和取得必要。

Node.js 的包是3个目录,当中包罗一个 JSON 格式的包表明文件
package.json。严俊符合 CommonJS 规范的包应该有所以下特征:

package.json 必须在包的顶层目录下;

  二进制文件应当在 bin 目录下;

  JavaScript 代码应该在 lib 目录下;

  文书档案应该在 doc 目录下;

  单元测试应该在 test 目录下。

1. 用作文件夹的模块

模块与公事是各样对应的。文件不仅能够是 JavaScript
代码或二进制代码,仍是可以够是1个文书夹。最简便的包,正是三个作为文件夹的模块

例子:

创制3个名为 somepackage  的文书夹,在中间成立 index.js,内容如下:

//somepackage/index.js

exports.hello = function() {

console.log(‘Hello.’);

};

然后在  somepackage 之外建立 getpackage.js,内容如下:

//getpackage.js

var somePackage = require(‘./somepackage’);

somePackage.hello();

运作 node getpackage.js,控制台将出口结果 Hello. 。

咱俩选取这种方法能够把文件夹封装为1个模块,即所谓的包。包平常是一些模块的集纳,在模块的底蕴上提供了更高层的空洞,约等于提供了一些稳定接口的函数库。通过定制

package.json,我们得以创建更复杂、更完美、更符合规范的包用于发布。

  1. 2.       package.json

在前面例子中的 somepackage 文件夹下,大家创立叁个号称 package.json
的文书,内容如

下所示:

{

“main” : “./lib/interface.js”

}

接下来将 index.js 重命名为 interface.js 并放入 lib
子文件夹下。以同一的点子重新调用这一个包,照旧得以平常使用。

Node.js 在调用有些包时,会首先检查包中 package.json 文件的 main 
字段,将其看成包的接口模块,假设 package.json 或 main
字段不存在,会尝试寻找 index.js 或 index.node 作为包的接口。

 

备考:package.json里面不能够有main{}之类的诠释,不然会报错

 

package.json是CommonJS 规定的用来叙述包的文件,完全符合规范的
package.json 文件应当包涵以下字段。

name
:包的称呼,必须是绝无仅有的,由小写英文字母、数字和下划线组成,不能够包涵空格。

description :包的简要说明。

version :符合语义化版本识别

keywords :关键字数组,常常用于搜索。

maintainers :维护者数组,每一种成分要含有 name 、 email (可选)、 web
(可选)字段。

contributors :进献者数组,格式与 maintainers
相同。包的撰稿人应该是进献者数组的第三个成分。

bugs :提交bug的地点,能够是网址或许电子邮件地址。

licenses :许可证数组,每种成分要包括 type (许可证的名目)和  url
(链接到许可证文本的地方)字段。

repositories :仓库托管地址数组,各个成分要含有 type  (仓库的门类,如 
git )、url (仓库的地点)和  path (相对于仓库的不二法门,可选)字段。

dependencies :包的正视,1个提到数组,由包名称和版本号组成。

 

例子:

{

“name”: “mypackage”,

“description”: “Sample package for CommonJS. This package demonstrates
the required

elements of a CommonJS package.”,

“version”: “0.7.0”,

“keywords”: [

“package”,

“example”

],

“maintainers”: [

{

“name”: “Bill Smith”,

“email”: “bills@example.com”,

}

],

“contributors”: [

{

“name”: “BYVoid”,

“web”: “http://www.byvoid.com/

}

],

“bugs”: {

“mail”: “dev@example.com”,

“web”: “http://www.example.com/bugs

},

“licenses”: [

{

“type”: “GPLv2”,

“url”: “http://www.example.org/licenses/gpl.html

}

],

“repositories”: [

{

“type”: “git”,

“url”: “http://github.com/BYVoid/mypackage.git

}

],

“dependencies”: {

“webkit”: “1.2”,

“ssl”: {

“gnutls”: [“1.0”, “2.0”],

“openssl”: “0.9.8”

}

}

}

 

Node.js 包管理器

Node.js包管理器,即npm是 Node.js 官方提供的包管理工科具,它早已成了
Node.js 包的正经发表平台,用于 Node.js 包的发布、传播、正视控制。npm
提供了命令行工具,使您能够一本万利地下载、安装、升级、删除包,也能够让您作为开发者公布并维护包。

 

本土格局和大局方式

地方情势:npm [install/i] [package_name]

全局格局:npm [install/i]  -g  [package_name]

 

为啥要选拔全局方式吧?多数时候并不是因为许多顺序都有大概用到它,为了削减多重副本而选用全局方式,而是因为地点情势不会登记 
PATH 环境变量。举例表明,大家设置supervisor
是为了在指令行中运转它,譬如直接运维 supervisor script.js,那时就必要在 
PATH环境变量中注册 supervisor。npm 本地情势仅仅是把包安装到
node_modules 子目录下,个中的 bin 目录没有包罗在 PATH 
环境变量中,不能够平素在指令行中调用。而当大家使用全局情势安装时,npm
会将包安装到系统目录,譬如 /usr/local/lib/node_modules/,同时
package.json 文件中 bin 字段包括的公文种被链接到
/usr/local/bin/。/usr/local/bin/ 是在 PATH
环境变量中暗许定义的,因此就能够一贯在指令行中运维 supervisor script.js
命令了。

 

 

 

创立全局链接

npm 提供了1个有趣的下令 npm
link,它的成效是在本土包和全局包里面创建符号链接。大家说过使用全局格局安装的包不能够直接通过require
使用,但经过  npm link 命令能够打破这一限量。举个例子,咱们早已因而  npm
install -g express 安装了  express ,那时在工程的目录下运转命令:

$ npm link express

./node_modules/express -> /usr/local/lib/node_modules/express

大家可以在 node_modules
子目录中发现3个对准安装到全局的包的标志链接。通过那种格局,大家就能够把全局包当本地包来使用了。

 

包的文告

*编排模块

1)新建文件夹,比如:somepackage

2) 该公文夹下新建js文件,比如:index.js

  js内容如下:

  exports.sayHello=function(){
    return “Hello,zhoudaozhang.”;
  };

 

*开头化包描述文件

选取cmd命令定位到somepackage文件夹

输入 npm init 并执行

npm的init命令可以扶助你生成package.json文件,那是自个儿的公文内容:

{
“name”: “somepackage_xiaotian”,
“version”: “1.0.0”,
“description”: “‘hehe'”,
“main”: “index.js”,
“scripts”: {
“test”: “echo \”Error: no test specified\” && exit 1″
},
“keywords”: [
“Hello”,
“world”
],
“author”: “zhou daozhang”,
“license”: “ISC”
}

 

*挂号包仓库账号

npm adduser

输入这些命令会有提醒输入用户名,密码,邮箱等资料

那和去官方源仓库https://www.npmjs.com/注册是一样的

 

*上传包

npm publish

倘诺上传成功会唤醒

+somepackage_xiaotian@1.0.0 不然上传铩羽

本条时候去https://www.npmjs.com/登陆仓库账号就可以看到自己的包啦

 

*安装包

npm install somepackage_xiaotian

经过此命令能够在世界上任一一台机器上设置somepackage_xiaotian了

 

宣布包进程或许会遇见很多标题,小编影像比较长远的是npm ERAV4PAJERO publish 403

You do not have permission to publish ‘somepackage’.Are you logged in as

the corrent user?:somepackage

趣味是本身没权力发表somepackage,并问作者是或不是采取了科学的账号,

那可能是somepackage被旁人发表过了啊,所以作者修改了package.json文件

把name改成somepackage_xiaotian.

 

*分析包

以此命令能够为你分析出脚下路线下能够由此模块路径找到的拥有包,并扭转重视树。

npm ls

 

 

全局对象Global

JavaScript 中有二个独特的对象,称为全局对象(Global
Object),它及其全数属性都得以在先后的任哪个地方方访问,即全局变量。在浏览器
JavaScript 中,平常 window  是全局对象,而 Node.js 中的全局对象是 
global ,全部全局变量(除了 global 自个儿以外)都以  global

指标的属性。

 

大局对象与全局变量

global 最根本的意义是当做全局变量的宿主

满意以下原则的变量是全局变量:

在最外层定义的变量;

  全局对象的品质;

  隐式定义的变量(未定义直接赋值的变量)。

注:在 Node.js
中您非常的小概在最外层定义变量,因为有着用户代码都以属于当前模块的,而模块本人不是最外层上下文

晋升:永远使用 var 
定义变量以免止引入全局变量,因为全局变量会传染命名空间,进步代码的耦合风险。

 

Process

process  是叁个全局变量,即  global 对象的性质。它用于描述当前 Node.js
进程情状的对象,提供了三个与操作系统的简短接口

 

process.argv 是命令行参数数组,第二个要素是 node,第3个成分是本子文件名

process.stdout 是行业内部输出流,平日大家使用的  console.log()
向专业输出打字与印刷字符,而  process.stdout.write() 函数提供了更底层的接口。

process.stdin
是标准输入流,初叶时它是被暂停的,要想从正规输入读取数据,你必须恢复生机流,并手动编写流的风云响应函数。

process.nextTick(callback) 的坚守是为事件循环设置一项职务,Node.js
会在下次风云循环调响应时调用  callback 。

 

http://nodejs.org/api/process.html详见掌握的地点

 

console

console  用于提供控制台正式输出

console.log() :向专业输出流打字与印刷字符并以换行符结束

console.error() :与 console.log() 用法相同,只是向专业错误流输出。

console.trace() :向专业错误流输出当前的调用栈。

 

常用工具  util

util  是1个 Node.js 宗旨模块,提供常用函数的聚集,用于弥补中心JavaScript 的作用过于简短的供不应求。

 

util.inherits

util.inherits(constructor, superConstructor)
是1个落到实处目的间原型继承的函数。

var util = require(‘util’);

function Base() {

this.name = ‘base’;

this.base = 1991;

this.sayHello = function() {

console.log(‘Hello ‘ + this.name);

};

}

Base.prototype.showName = function() {

console.log(this.name);

};

function Sub() {

this.name = ‘sub’;

}

util.inherits(Sub, Base);

var objBase = new Base();

objBase.showName();

objBase.sayHello();

console.log(objBase);

var objSub = new Sub();

objSub.showName();

//objSub.sayHello();

console.log(objSub);

 

结果:

base

Hello base

{ name: ‘base’, base: 1991, sayHello: [Function] }

sub

{ name: ‘sub’ }

 

以此只好一而再原型里面包车型地铁习性和办法

 

util.inspect

 

util.inspect(object,[showHidden],[depth],[colors])
是二个将轻易对象转换为字符串的章程,常常用于调试和错误输出。它至少接受一个参数 
object ,即要转换的指标。

showHidden  是2个可选参数,若是值为  true ,将会输出愈多隐蔽音讯。

depth 
表示最大递归的层数,要是目的很复杂,你可以内定层数以决定输出新闻的多

少。即便不钦命 depth ,私下认可会递归2层,内定为  null 
表示将不限递归层数完整遍历对象。

万一 color 值为  true ,输出格式将会以 ANSI
颜色编码,经常用于在巅峰突显更理想的机能。

 

注:util.inspect  并不会简单地一贯把目的转换为字符串,尽管该对

象定义了 toString  方法也不会调用。

 

 

module.exports 和exports的区别?

Module.exports才是真正的接口,exports只可是是它的二个支持理工科程师具。 最终回到给调用的是Module.exports而不是exports。

所有的exports采访到的质量和艺术,都赋值给了Module.exports。当然,那有个前提,就是Module.exports自作者不享有别的性质和措施。假如,Module.exports已经具有一些属性和方法,那么exports收集来的消息将被忽略。

 

那便是 伊夫ntEmitter 最简便的用法。接下来大家介绍一下 伊夫ntEmitter
常用的API。

  伊芙ntEmitter.on(event, listener) 
为内定事件注册3个监听器,接受3个字符串  event  和一个回调函数 
listener 。

  EventEmitter.emit(event, [arg1], [arg2], […]) 发射  event 
事件,传递若干可选参数到事件监听器的参数表。

  伊夫ntEmitter.once(event, listener) 
为内定事件注册2个单次监听器,即监听器最五只会接触一次,触发后立即解除该监听器。

  伊夫ntEmitter.removeListener(event, listener)
移除钦点事件的有个别监听器, listener  必须是该事件早已注册过的监听器。

 

 

文件系统  fs

fs
模块是文件操作的包裹,它提供了文本的读取、写入、更名、删除、遍历目录、链接等
POSIX 文件系统操作。与别的模块不一致的是, fs
模块中兼有的操作都提供了异步的和共同的多个版本,例如读取文件内容的函数有异步的 
fs.readFile() 和一道的fs.readFileSync() 。

 

fs.readFile

fs.readFile(filename,[encoding],[callback(err,data)]) 是最简便的读取

文本的函数。它接受一个必选参数  filename
,表示要读取的文书名。第二个参数  encoding是可选的,表示文件的字符编码。
callback 是回调函数,用于吸收接纳文件的情节。倘使不钦赐  encoding ,则 
callback 就是第二个参数。回调函数提供七个参数  err 和  data , err
代表有没有不当发生, data 是文件内容。若是钦点了  encoding , data
是3个解析后的字符串,不然  data 将会是以  Buffer 情势表示的二进制数据。

 

例;

 

以  Buffer 方式表示的二进制数据

var fs = require(‘fs’);

fs.readFile(‘content.txt’, function(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

});

 

encoding 指确定人员编制码

var fs = require(‘fs’);

fs.readFile(‘content.txt’, ‘utf-8’, function(err, data) {

if (err) {

console.error(err);

} else {

console.log(data);

}

});

 

fs.readFileSync

fs.readFileSync(filename, [encoding]) 是  fs.readFile
同步的版本。它承受的参数和  fs.readFile
相同,而读取到的文件内容会以函数重回值的款型重回。假若有不当产生, fs
将会抛出分外,你必要采取  try 和  catch 捕捉并拍卖万分。

 

Fs.read

fs.read(fd, buffer, offset, length, position, [callback(err, bytesRead,

buffer)]) 是 POSIX  read 函数的卷入,相比较fs.readFile
提供了更底层的接口。 fs.read的效用是从内定的文书讲述符fd
中读取数据并写入  buffer 指向的缓冲区对象。offset 是buffer
的写入偏移量。length 是要从文件中读取的字节数。position 是文件读取的苗子

职位,如若  position 的值为  null
,则会从此时此刻文件指针的岗位读取。回调函数字传送递bytesRead 和  buffer
,分别代表读取的字节数和缓冲区指标。

 

用的时候,和fs.open一起用

 

 

var fs = require(‘fs’);

fs.open(‘content.txt’, ‘r’, function(err, fd) {

if (err) {

console.error(err);

return;

}

var buf = new Buffer(8);

fs.read(fd, buf, 0, 8, null, function(err, bytesRead, buffer) {

if (err) {

console.error(err);

return;

}

console.log(‘bytesRead: ‘ + bytesRead);

console.log(buffer);

})

});

运作结果则是:

bytesRead: 8

<Buffer 54 65 78 74 20 e6 96 87>

 

HTTP 服务器与客户端

 

工程的社团

Express 都生成了什么样文件,除了 package.json,它只发生了多个 JavaScript
文件 app.js 和 routes/index.js。模板引擎 ejs 也有两文本 index.ejs
和layout.ejs,其它还有样式表 style.css。上边来详细看看那多少个文本。

  1. app.js

routes  是贰个文书夹情势的本土模块,即 ./routes/index.js
,它的法力是为钦定路线协会重临内容,约等于 MVC 框架结构中的控制器。

  1. routes/index.js

routes/index.js 是路由文件,也正是控制器,用于集体展现的剧情:

exports.index = function(req, res) {

res.render(‘index’, { title: ‘Express’ });

};

app.js 中通过 app.get(‘/’, routes.index); 将“ / ”路径映射到 
exports.index函数下。当中只有七个讲话  res.render(‘index’, { title:
‘Express’ }) ,功效是调用模板解析引擎,翻译名为 index
的模版,并传到2个对象作为参数,那一个目的唯有三个

属性,即  title: ‘Express’ 。

  1. index.ejs

index.ejs 是模板文件,即 routes/index.js 中调用的模版,内容是:

<h1><%= title %></h1>

<p>Welcome to <%= title %></p>

它的根底是 HTML 语言,个中富含了形如<%= title
%>的竹签,功用是呈现引用的变量,即  res.render
函数第二个参数字传送入的靶子的本性。

  1. layout.ejs  (新的里边,没有这么些)

模板文件不是孤立展示的,私下认可景况下全部的沙盘都再而三自
layout.ejs,即<%- body %>

一部分才是差别平常的始末,别的部分是共有的,能够看成是页面框架。

<!DOCTYPE html>

<html>

<head>

<title><%= title %></title>

<link rel=’stylesheet’ href=’/stylesheets/style.css’ />

</head>

<body>

<%- body %>

</body>

</html>

 

REST 风格的路由规则

特点状态转移(Representational State Transfer),它是一种基于 HTTP
协议的网络采纳的接口风格,足够利用 HTTP 的点子完毕合并风格接口的服务。

铁岭是指没有副功能,即请求不会对能源发生变动,一连走访数十次所获得的结果不受访问者的熏陶。而幂等指的是重新请求数次与二次呼吁的功效是一样的,比如获取和换代操作是幂等的,那与新增区别。删除也是幂等的,即重复删除贰个财富,和删除一回是一致的。

 

 

在 MVC 框架结构中,模板引擎包涵在劳务器端。

听新闻说 JavaScript 的模板引擎有为数不少种达成,大家推荐使用 ejs (Embedded
JavaScript),因为它可怜简易,而且与 Express 集成杰出。由于它是正统
JavaScript 达成的,由此它不但能够运作在服务器端,还是能运营在浏览器中。

 

ejs 的标签系统万分简单,它只有以下3种标签。

  <% code %>:JavaScript 代码。

  <%= code %>:显示替换过 HTML 特殊字符的剧情。

  <%- code %>:展现原始 HTML 内容。

 

视图助手

Express
提供了一种叫做视图帮手的工具,它的效益是同意在视图中走访1个大局的函数或对象,不用每回调用视图解析的时候单独传入。后边提到的
partial 就是三个视图帮手。

是因为ejs的进步,《node.js开发指南》中运用的  partial
函数已经吐弃,使用foreach,include代替

<%- partial(‘listitem’,items) %>

修改为:

1

2

3

4

<ul><% items.forEach(function(listitem){%>

    <% include listitem%>

    <%}) %>

</ul>

 

 

next()

Express 提供了路由控制权转移的不二法门,即回调函数的第八个参数 next
,通过调用next() ,会将路由控制权转移给末端的规则,例如:

app.all(‘/user/:username’, function(req, res, next) {

console.log(‘all methods captured’);

next();

});

app.get(‘/user/:username’, function(req, res) {

res.send(‘user: ‘ + req.params.username);

});

当访问被匹配到的不二法门时,如
http://localhost:3000/user/carbo,会发现终端中打印了  allmethods
captured ,而且浏览器中显得了  user: carbo
。那表明请求先被第二条路由规则捕获,完结 console.log  使用 next()
转移控制权,又被第贰条规则捕获,向浏览器重返了音信。

 

这是一个不行政管理用的工具,能够让我们随便地贯彻中间件,而且还是可以增高代码的复用程度。例如大家针对1个用户查询音信和改动音讯的操作,分别对应了
GET 和 PUT 操作,而双方共有的2个手续是检查用户名是或不是合法,由此能够透过
next()  方法实现:

var users = {

‘byvoid’: {

name: ‘Carbo’,

website: ‘http://www.byvoid.com

}

};

app.all(‘/user/:username’, function(req, res, next) {

// 检查用户是或不是存在

if (users[req.params.username]) {

next();

} else {

next(new Error(req.params.username + ‘ does not exist.’));

}

});

app.get(‘/user/:username’, function(req, res) {

// 用户一定存在,直接显示

res.send(JSON.stringify(users[req.params.username]));

});

app.put(‘/user/:username’, function(req, res) {

// 修改用户音信

res.send(‘Done’);

});

上面例子中, app.all 
定义的这些路由规则实际上起到了中间件的机能,把一般请求

的同等部分提取出来,有利于代码维护别的 next
方法假若接受了参数,即意味着发生了不当。

选用那种措施能够把错误检查分段化,下跌代码耦合度。

 

天涯论坛网站进度中发觉的局部题材;

壹 、          css和javascritp的路子不用写相对路径,例:

<script src=”/javascripts/jquery-1.11.3.js”></script>
<script src=”/javascripts/bootstrap.js”></script>
<link rel=’stylesheet’ href=’/stylesheets/bootstrap.css’ />
<link href=”/stylesheets/bootstrap-responsive.css”
rel=”stylesheet”>

贰 、          app.js里面要加那些

3、     var partials = require('express-partials');

app.use(partials());

前面要安装express-partials模块,npm install express-partials –g

3地点那些要写在

app.set('views', path.join(__dirname, 'views'));

app.set('view engine', 'ejs');

后面

 

 

数据库的格式是由表(table)、行(row)、字段(田野先生)组成的。表有固定的布局,规定了

每行有何字段,在创建时被定义,之后修改很拮据。行的格式是一样的,由若干个固定的字段组成。每一个表恐怕有多少个字段作为目录(index),那在那之中有的是主键(primary
key),用于约束表中的数量,还有唯一键(unique
key),确认保障字段中不存放重复数据。表和表之间

唯恐还有互动的羁绊,称为外键(foreign
key)。对数据库的历次查询都要以行为单位,复杂的查询包含嵌套查询、连接查询和交叉表查询。

怀有那几个成效的数据库被叫做关系型数据库,关系型数据库一般采取一种叫做
SQL(Structured Query Language)的询问语言作为接口,因而又叫做 SQL
数据库。典型的 SQL 数据库有 MySQL、Oracle、Microsoft SQL
Server、PostgreSQL、SQLite,等等。

 

 

 

会话

对话是一种持久的网络协议,用于达成服务器和客户端之间的部分互为行为。会话是二个比连接粒度更大的定义,1次对话大概带有数十三遍接连,每趟延续都被认为是会话的三遍操作。在互联网使用开发中,有

必备实现会话以赞助用户交互。例如网上购物的风貌,用户浏览了七个页面,购买了一些物品,那么些请求在连续总是中做到。许多应用层网络协议都是由会话协理的,如
FTP、Telnet 等,而 HTTP
协议是无状态的,自身不援助会话,由此在并未额外手段的协理下,前面场景中服务器不精晓用户购买了怎么样。

为了在无状态的 HTTP 协议之上达成会话,Cookie 诞生了。Cookie
是一些储存在客户端的音信,每趟两次三番的时候由浏览器向服务器递交,服务器也向浏览器发起存款和储蓄Cookie 的请求,依靠那样的手法服务器能够辨认客户端。大家一般意义上的 HTTP
会话效能正是这样

落实的。具体来说,浏览器首次向服务器发起呼吁时,服务器生成2个唯一标识符并发送给客户端浏览器,浏览器将那个唯一标识符存款和储蓄在
Cookie
中,将来每一趟再发起呼吁,客户端浏览器都会向服务器传送那一个唯一标识符,服务器通过那些唯一标识符来识别用户。

 

Underscore模块