zoukankan      html  css  js  c++  java
  • NodeJS学习笔记(一)

    1 JS是脚本语言,脚本语言都需要一个解析器才能运行。对于写在HTML页面里的JS,浏览器充当了解析器的角色。而对于需要独立运行的JS,NodeJS就是一个解析器。

    2 运行在浏览器中的JS的用途是操作DOM,浏
    览器就提供了 document 之类的内置对象。而运行在NodeJS中的JS的用途是操作磁盘文件或搭
    建HTTP服务器,NodeJS就相应提供了 fs、http 等内置对象。

    3 在Linux系统下,使用NodeJS监听80或443端口提供HTTP(S)服务时需要root权限.
    一种方式是使用 sudo 命令运行NodeJS。例如通过以下命令运行的 server.js 中有权限使用80
    和443端口。一般推荐这种方式,可以保证仅为有需要的JS脚本提供root权限。
    $ sudo node server.js

    4 编写稍大一点的程序时一般都会将代码模块化。在NodeJS中,一般将代码合理拆分到不同的JS
    文件中,每一个文件就是一个模块,而文件路径就是模块名。
    在编写每个模块时,都有 require、exports、module 三个预先定义好的变量可供使用。

    require 函数用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对
    象。模块名可使用相对路径(以 ./ 开头),或者是绝对路径(以 / 或 C: 之类的盘符开头)。模块名中的 .js 扩展名可以省略。
    如果是加载和使用一个JSON文件,模块名中 .json 扩展名不可省略。

    exports 对象是当前模块的导出对象,用于导出模块公有方法和属性。别的模块通过 require
    函数使用当前模块时得到的就是当前模块的 exports 对象。

    通过 module 对象可以访问到当前模块的一些相关信息,但最多的用途是替换当前模块的导出
    对象。

    5 一个模块中的JS代码仅在模块第一次被使用时执行一次,并在执行过程中初始化模块的导出对
    象。之后,缓存起来的导出对象被重复利用。
    6 通过命令行参数传递给NodeJS以启动程序的模块被称为主模块。主模块负责调度组成整个程序
    的其它模块完成工作。

    7 虽然一般我们使用JS编写模块,但NodeJS也支持使用C/C++编写二进制模块。编译好的二进制模
    块除了文件扩展名是 .node 外,和JS模块的使用方式相同.但是,除非JS模块不能满足需求,否则不要轻易使用二进制模块

    8 NodeJS是一个JS脚本解析器,任何操作系统下安装NodeJS本质上做的事情都是把
    NodeJS 执行程序复制到一个目录,然后保证这个目录在系统PATH环境变量下,以便终
    端下可以使用node命令。

    9 NodeJS使用 CMD 模块系统,主模块作为程序入口点,所有模块在执行过程中只初始化
    一次。

    10 NodeJS定义了一个特殊的 node_modules 目录用于存放模块。实际工程中,node_modules里主要存放第三方包.
    如某个模块的绝对路径是 /home/user/hello.js,在该模块中使用 require('foo/bar') 方式加载模
    块时,则NodeJS依次尝试使用以下路径。
    ◦ /home/user/node_modules/foo/bar
    ◦ /home/node_modules/foo/bar
    ◦ /node_modules/foo/bar

    11 与PATH环境变量类似,NodeJS允许通过NODE_PATH环境变量来指定额外的模块搜索路
    径。NODE_PATH环境变量中包含一到多个目录路径,路径之间在*nix下使用 : 分隔;
    例如定义了以下NODE_PATH环境变量:
    NODE_PATH=/home/user/lib:/home/lib
    当使用 require('foo/bar') 的方式加载模块时,则NodeJS依次尝试以下路径。
    ◦ /home/user/lib/foo/bar
    ◦ /home/lib/foo/bar

    12 JS模块的基本单位是单个JS文件,但复杂些的模块往往由多个子模块组成。为了
    便于管理和使用,可以把由多个子模块组成的大模块称做包,并把所有子模块放在同一个目
    录里。在组成一个包的所有子模块中,需要有一个入口模块,入口模块的导出对象被作为包的导出对象。

    13 设置包的入口模块:
    (1) 使用index.js作为入口模块的文件名,则加载模块时可以使用模块所在目录的路径代替模块文件路径.
    以下两条语句等价。
    var cat = require('/home/user/lib/cat');
    var cat = require('/home/user/lib/cat/index');
    (2) 设置package.json文件:想自定义入口模块的文件名和存放位置,就需要在包目录下包含一个 package.json 文
    件,并在其中指定入口模块的路径。假如某个cat模块包的package.json 内容如下。
    {
    "name": "cat",
    "main": "./lib/main.js"
    }
    则指定了main.js作为入口模块,并且可以直接使用 require('/home/user/lib/cat') 的方式加载模块。NodeJS
    会根据包目录下的 package.json 找到入口模块所在位置。

    14 在工程目录下打开终端,使用以下命令来下载三方包。
    $ npm install argv

    如果想要下载指定版本的话,可以在包名后边加上@<version>,例如通过以下命令可下载0.0.1版的 argv。
    $ npm install argv@0.0.1

    如果使用到的三方包比较多,在终端下一个包一条命令地安装未免太人肉了。因此NPM对
    package.json 的字段做了扩展,允许在其中申明三方包依赖。因此,上边例子中的
    package.json 可以改写如下:
    {
    "name": "node-echo",
    "main": "./lib/echo.js",
    "dependencies": {
    "argv": "0.0.2"
    }
    }

    15 使用NodeJS编写的东西,要么是一个包,要么是一个命令行程序,而前者最终也会用于开发后
    者。

    16 设置命令行程序:
    假如用NodeJS写了一个程序,放在/home/vagrant/workspace/node-echo/bin/node-echo.js这个位置.
    为了能在任何目录下都能运行该程序,即把JS文件当作shell脚本来运行,需要使用以下终端命令:
    (1) 在shell脚本中,可以通过 '#!' 注释来指定当前脚本使用的解析器。所以首先在
    node-echo.js 文件顶部增加以下一行注释,表明当前脚本使用NodeJS解析。
    #! /usr/bin/env node
    (2) 然后,使用以下命令赋予 node-echo.js 文件执行权限。
    $ chmod +x /home/vagrant/workspace/node-echo/bin/node-echo.js
    (3) 最后,在PATH环境变量中指定的某个目录下,例如在 /usr/local/bin 下边创建
    一个软链文件,文件名与我们希望使用的终端命令同名,命令如下:
    $ sudo ln -s /home/vagrant/workspace/node-echo/bin/node-echo.js /usr/local/bin/node-echo

    这样处理后,就可以在任何目录下使用node-echo命令了。

    17 实现文件拷贝:

    1 var fs = require('fs');
    2 function copy(src, dst) {
    3     fs.createReadStream(src).pipe(fs.createWriteStream(dst));
    4 }
    5     function main(argv) {
    6     copy(argv[0], argv[1]);
    7 }
    8 main(process.argv.slice(2));

    18 process 是一个全局变量,可通过 process.argv 获得命令行参数。由于 argv[0] 固定
    等于NodeJS执行程序的绝对路径,argv[1] 固定等于主模块的绝对路径,因此第一个命令
    行参数从 argv[2] 这个位置开始。

    19
    JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一个与 String 对
    等的全局构造函数 Buffer 来提供对二进制数据的操作。
    Buffer 与字符串类似,除了可以用 .length 属性得到字节长度外,还可以用 [index] 方式
    读取指定位置的字节.
    Buffer 与字符串能够互相转化,例如可以使用指定编码将二进制数据转化为字符串:
    var str = bin.toString('utf-8');
    或者反过来,将字符串转换为指定编码下的二进制数据:
    var bin = new Buffer('hello', 'utf-8');

    Buffer 与字符串有一个重要区别。字符串是只读的,并且对字符串的任何修改得到的都是一个
    新字符串,原字符串保持不变。至于 Buffer,更像是可以做指针操作的C语言数组。例如,可
    以用 [index] 方式直接修改某个位置的字节。
    bin[0] = 0x48;
    而 .slice 方法也不是返回一个新的 Buffer,而更像是返回了指向原 Buffer 中间的某个位
    置的指针,因此对 .slice 方法返回的 Buffer 的修改会作用于原 Buffer.

    var bin = new Buffer([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]);
    var sub = bin.slice(2);
    sub[0] = 0x65;
    console.log(bin); // => <Buffer 68 65 65 6c 6f>

    20 如果想要拷贝一份 Buffer,得首先创建一个新的 Buffer,并通过 .copy 方法把原
    Buffer 中的数据复制过去。这个类似于申请一块新的内存,并把已有内存中的数据复制过去。
    以下是一个例子。

    1 var bin = new Buffer([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]);
    2 var dup = new Buffer(bin.length);
    3 bin.copy(dup);
    4 dup[0] = 0x48;
    5 console.log(bin); // => <Buffer 68 65 6c 6c 6f>
    6 console.log(dup); // => <Buffer 48 65 65 6c 6f>

    总之,Buffer 将JS的数据处理能力从字符串扩展到了任意二进制数据。

  • 相关阅读:
    [日常工作]WorkStation 使用端口转发的方式使用宿主机IP地址提供服务
    [日常工作]虚拟机或者实体机转换成HyperV虚拟机的方法
    [linux学习]sysctl 以及 net.ipv4.ip_forward
    [自学]Docker system 命令 查看docker镜像磁盘占用情况 Docker volume 相关
    Docker 修改默认存储路径的一个方法
    [学习笔记]Ubuntu下安装配置SQLSERVER2017
    VSCODE安装以及使用Python运行调试代码的简单记录
    Win2012r2 以及win2016 安装.NET3.5
    Win2016以及win10 IIS10 下安装IEwebcontrol的方法
    [日常工作]协助同事从不能开机的机器上面获取资料信息
  • 原文地址:https://www.cnblogs.com/leaf526/p/3617452.html
Copyright © 2011-2022 走看看