Node.js笔记

100 阅读5分钟

Module

CommonJS

// file.js
const fs = require('fs'); // 导入
function myFunc() {}
exports.func = myFunc; // 导出
exports.valueOne = 123; // 导出
// 其他地方能用 
const { func, valueOne } = require('./file');
// 文件只导出一个
class Fox {}
module.exports = new Fox(); 
// 这是导出一个新的实例 也可导出class再在导入的地方

ECMAScript 6

// index.js
import { func, valueOne } from './file';
export const Text = 'aaa';
export default new Fox();

MongoDB

本地导出与恢复。(默认导出到当前命令行下的dump文件夹)

# localhost
mongodump --db <DATABASE> [-o|--out <DIRNAME>]
mongorestore

mongodb atlas 集群备份和恢复

# atlas cluster
mongodump --host <REPLICA-SET-NAME/CLUSTER-SHARD-00-00,CLUSTER-SHARD-00-01,CLUSTER-SHARD-00-02> --ssl --username <ADMINUSER> --password <PASSWORD> --authenticationDatabase admin --db <DATABASE>
mongorestore --host <REPLICA-SET-NAME/CLUSTER-SHARD-00-00,CLUSTER-SHARD-00-01,CLUSTER-SHARD-00-02> --ssl --username <ADMINUSER> --password <PASSWORD> --authenticationDatabase admin 

Date

let time
time = Date.now()
# 1586335565920
time = new Date(159000000000)
# Wed Jan 15 1975 14:40:00 GMT+0800
time.toJSON()
# "1975-01-15T06:40:00.000Z"
time.getTime()
# 159000000000

JS deepClone or structuredClone()

function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }
  const clone = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;
}

Array

Object.keys(array).forEach(index => { array[index] });
for (let index in array) { array[index] };
// 扩展运算符(spread)
const arr1 = [1];
const arr2 = [2, 3];
arr1.push(...arr2); // [1, 2, 3]
const arr3 = [...arr2, 5]; // [2, 3, 5]
  • 拷贝: 可以使用数组实例的concat方法或扩展运算符[...arr]来深拷贝一个数组 (即数组更改互不影响), 但是如果数组里有对象元素则是浅拷贝 (更改对象内容会同步更改, 拷贝了对象的引用). 更多可参考link.
deepClone = (element) => {
  if(typeof element !== 'object') return element;
  if(element === null) return null;
  return element instanceof Array 
    ? element.map(item => deepClone(item))
    : Object.entries(element)
    .reduce((pre,[key,val])=> ({...pre, [key]: deepClone(val)}), {});
}

Function

参数默认值

func = function (url, {
  async = true,
  global = true,
  // ... more default config
} = {}) {
  // ... do stuff
};

Closure 闭包

const myFunc = (function() {
  let t = 1;
  return function() { return t++; }
})();

Number

js中所有数字都存储成 64 位浮点数, 但所有按位运算都以 32 位二进制数执行.

二进制比特位移运算MDN, JavaScript 位运算符

  • 符号位(Sign) 1bit (0正数1负数)
  • 指数位(Exponent) 32位 8bit 64位 11bit
  • 尾数(Mantissa) 32位 23bit 64位 52bit
(-1 >>> 0).toString(2);
// "11111111111111111111111111111111" 32位, 十进制 -1
(-1 >>> 1).toString(2);
// "01111111111111111111111111111111" 
// 十进制 2147483647, 等于 2^31 - 1 (32位最大值)
1 << 31 // 左移31位
//  10000000000000000000000000000000
// 十进制 -2147483648, 等于-(2^31) (32位最小值) 

二进制转十进制 parseInt(110, 2); // 6. 64位最大可表示2^53

数值精度: wangdoc.. 比特位转化:IEEE-754 Floating Point Converter.

Classes ref

class FooBase {
    static a = 0;
    public x: number;
    private y: number;
    protected z: number;
}
class Child extends FooBase {
    constructor() { super() }
}

FooBase.a; // 可以访问, 所有FooBase类
Child.a;   // 和它的子类都共享同一个值

// EFFECT ON INSTANCES
var foo = new FooBase();
foo.x; // okay
foo.y; // ERROR : private
foo.z; // ERROR : protected

// EFFECT ON CHILD CLASSES
class FooChild extends FooBase {
    constructor() {
      super();
        this.x; // okay
        this.y; // ERROR: private
        this.z; // okay
    }
}

Buffer 🔨

Buffer 对象用于以字节序列的形式来表示二进制数据。 文档



ES6 🔨

不用var因其存在变量提升,letconst块级作用域,不能声明前调用。

变量解构赋值,如[x, y] = [y, x],详见 link

字符串 (unicode,字符串for ... of遍历,模板字符串)link。 字符串转十六进制 Unicode link

字符串对象的方法 - includesstartsWithendsWith参数皆为字符串。 还有方法padStartpadEnd第一个参数为长度,第二参数为填充。 trim方法想必都不陌生,还有对应的trimStarttrimEnd

'1'.padStart(3, '0') // "001"

RegExp ES6, MDN

Math.trunc(-4.9)       // -4 去除小数部分
Math.cbrt(8)           // 2 开立方根 
Math.pow(Math.abs(8), 1/3)
Math.hypot(3, 4);      // 5 (3的平方加上4的平方,等于5的平方)

函数: 使用箭头函数需要注意this作用域等 MDN使用注意点, MDN不适用场合

Path

__dirname     // 文件的文件夹绝对路径路径
__filename    // 文件的绝对路径
process.cwd() // 执行时的终端工作路径 (同./)

使用内置库path,中文文档

const path = require('path');
path.parse('/dir1/dir2/file.txt');
// { root: '/', dir: '/dir1/dir2', base: 'file.txt', ext: '.txt', name: 'file' }
  • path.resolve() 方法会将路径或路径片段的序列解析为绝对路径。
  • path.join()将所有给定的path片段连接到一起, 规范化生成的路径.

Promise 🔨

传入函数中使用的resolve(..), reject(..)会调用.then()里的函数.

const promise = new Promise ((resolve, reject) => {
    const res = "message";
    if (false) reject("error"); // 出现异常reject
    // throw new Error("error message");
    resolve(res);
}).then(response => { // success (in then)
    return response; // "message"
}, function (rejectMsg) { // rejected (in then)
    console.log(rejectMsg); // "error"
}).catch(error => {
    console.log(error);
});

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

yarn audit fix ?

# Generate the package-lock.json file without installing node modules
npm install --package-lock-only
# Fix the packages and update the package-lock.json file
npm audit fix
# Remove the yarn.lock file and import the package-lock.json file into yarn.lock
rm yarn.lock
yarn import
# Remove the package-lock.json file
rm package-lock.json

npm registry

npm config set registry https://registry.npmmirror.com
npm config set registry https://registry.npmjs.org