0%

MongoDB 数据库

MongoDB 的数据逻辑结构:文档(document)、集合(collection)、数据库(database)。

  • 文档(document):由键值对构成,相当于关系数据库中的一行记录。
  • 集合(collection):多个文档组成一个集合,相当于关系数据库的表。
  • 数据库(database):多个集合逻辑上组织在一起,就是数据库。

一个 MongoDB 实例支持多个数据库(database)。

MongoDB 数据库结构

阅读全文 »

Node.js 网络通信模块 实现的通信方式
net TCP
http HTTP
http2 HTTP/2
https HTTPS
dgram UDP
阅读全文 »

主要内容:利用 Node.js 爬取一个网页,通过第三方模块 cheerio.js 分析这个网页的内容,最后将这个网页的图片保存在本地。

整体思路

  • 通过第三方模块 request 请求网页地址,从而得到整个网页的 DOM 结构。
  • 根据 DOM 结构利用 cheerio 模块分析出图片文件的地址,再次请求这个地址,最后将得到的图片数据储存在本地。

项目目录结构

image

阅读全文 »

Node.js 使用 fs(File System)模块来操作文件。文件系统模块有两种不同的方法:同步方法 / 异步方法。

同步和异步

  • 异步方法的最后一个参数总是一个完整的回调函数,该回调函数的第一个参数永远是异常(err)。
  • 异步的方法不能保证执行顺序,因此注意文件操作的顺序很重要。

异步方法示例:

const fs = require('fs');

// 异步操作读取文件
const path = '/Users/huqilin/Desktop/node/test/tmp/hello.html';
fs.unlink(path, (err) => {
  if (err) throw err;
  console.log('成功删除 /tmp/hello');
});
阅读全文 »

CmmonJS 规范

CommonJS 是一个项目,其目标是在 Web 浏览器之外为 JavaScript 建立模块生态系统的约定。其创建的主要原因是缺乏普遍接受的 JavaScript 脚本模块单元形式,其可以在不同于传统网络浏览器提供的环境中重复使用,例如,运行 JavaScript 脚本的 Web 服务器或本机桌面应用程序。

详细参考:CommonJS 规范

模块加载原理与加载方式

  • Node 中的模块:
    1. 核心模块 / 原生模块:Node 提供的模块。
    2. 文件模块:用户编写的模块。
  • Node 引入模块的步骤:路径分析 —> 文件定位 —> 编译执行
  • 加载速度:核心模块比文件模块加载速度更快。

优先从缓存加载

  • Node 对引入过的模块都会进行缓存,以减少二次引入时的开销。而且缓存的是编译和执行之后的对象。
  • require() 方法是一个同步 I/O 操作
  • require() 方法对相同模块的二次加载一律采用缓存优先的方式。
  • 加载次序:缓存中加载 - 核心模块 - 文件模块 - node_modules 模块。
阅读全文 »

Node.js 安装

# 安装 node.js v10.12.0
$ wget -qO- https://deb.nodesource.com/setup_10.x | sudo -E bash -
$ sudo apt-get install -y nodejs

# 要从 npm 编译和安装原生插件,您可能还需要安装构建工具
$ sudo apt-get install -y build-essential 

# 检查当前 node.js 版本
$ node -v      
v11.14.0

# 检查当前 npm 版本
$ npm -v
6.9.0

$ sudo apt-get upgrade nodejs    ## 更新 node.js
$ sudo apt-get remove nodejs     ## 卸载 node.js

# 更新 npm
$ npm i -g npm

参考:官方文档:通过包管理器方式安装 Nodejs

阅读全文 »

函数

参考:JavaScript 教程:函数 @wangdao.com

// 定义
function functionName(arg0, arg1,...argN) {
    statments
}

// 示例代码
function sayHi(num1, num2) {
    alert("Hello " + arguments[0] + "," + arguments[1]); // 用类似数组的方式访问传入的参数
    alert(arguments.length); // 传入参数的个数

    if(arguments.length == 1) {
        alert(arguments[0] + 10);
    }else if {
        alert(arguments[0] + num2);
    }
}

// 函数体内通过 arguments 对象访问参数数组。
// arguments 与 命名参数的内存空间是相互独立的;
// ***特性:单向影响***:修改 arguments 的值会自动映射同步到命名参数上,反之则不能;
// arguments 对象的长度由传入的参数个数决定;
  • ECMAScript 函数的重要特点:命名的参数只是提供便利,但不是必须的。

  • ECMAScript 中的参数在内部是用一个数组来表示的。

  • 函数中 arguments.length 属性可以返回传入参数的个数,实际上,函数的 length 属性与实际传入的参数个数无关,只反映函数预期传入的参数个数

    <!–hexoPostRenderEscape:

    function howManyArgs () {
    console.log(arguments.length);
    }

howManyArgs(“string”, 45); //2
howManyArgs(); //0
howManyArgs(12); //1
:hexoPostRenderEscape–>

  • arguments 对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的。

  • 参数:没有传递值的命名参数将自动被赋予 undefined 值。

  • 由于不存在函数签名的特性,ECMAScript 函数不能重载。(就是函数名相同、参数的个数不同的函数)。

  • 无须指定函数的返回值,因为任何 ECMAScript 函数都可以在任何时候返回任何值。 实际上,未指定返回值的函数返回的是一个特殊的 undefined 值。

函数的传值

函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递(passes by value)。这意味着,在函数体内修改参数值,不会影响到函数外部。

如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递(pass by reference)。也就是说,传入函数的原始值的地址,因此在函数内部修改参数,将会影响到原始值。

函数的作用域

函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。

var a = 1;
// 函数 x 的作用域绑定在外层
var x = function () {
  console.log(a);
};

function f() {
  var a = 2;
  x(); // x 函数执行时,所处的是定义时的作用域。
}

f() // 1

立即调用的函数表达式(IIFE)

在定义函数之后,立即调用该函数:

(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();

函数表达式

定义函数的方式:

  1. 函数声明;
  2. 函数表达式;
  3. 构造函数;
阅读全文 »