360 前端星 Day3

6 正则表达式

创建

字面量创建

const reg = /[a-z]\d+[a-z]/i;

优点

  • 简单方便
  • 不需要考虑二次转义

缺点

  • 子内容无法重复使用
  • 过长的正则导致可读性差

使用 RegExp 构造函数

const alphabet = '[a-z]';
const reg = new RegExp(`${alphabet}\\d+${alphabet}`, 'i');

优点

  • 子内容可以重复使用
  • 可以通过控制子内容的粒度提高可读性

缺点

  • 二次转义的问题非常容易导致 bug
const reg = new RegExp(`\d+`);
reg.test('1'); // false
reg.test('ddd'); // true

正则表达式的常见用法

test()

RegExp.prototype.test()

const reg = /[a-z]\d+[a-z]/i;

reg.test('a1a'); // true
reg.test('1a1'); // false
reg.test(Symbol('a1a')); // TypeError

输入

要求输入字符串,如果输入的不是字符串类型,会尝试进行类型转换,转换失败会抛出 TypeError

输出

true 或者 false,表示匹配成功或失败

source 和 flags

sourceflags

const reg = /[a-z]\d+[a-z]/ig;

reg.source; // "[a-z]\d+[a-z]"
reg.flags; // "gi"

get RegExp.prototype.source

返回当前正则表达式的模式文本的字符串

get RegExp.prototype.flags

es2015新增,返回当前正则表达式的修饰符的字符串,会对修饰符按照字母升序进行排序

exec() 和 match()

RegExp.prototype.exec() 和 String.prototype.match()

输入

RegExp.prototype.exec 要求输入字符串,遇到非字符串类型会尝试转换

String.prototype.match 要求输入正则表达式,遇到其它类型会先尝试转成字符串,再以字符串为 source 创建正则表达式

输出

匹配成功,返回匹配结果

匹配失败,返回 null

二者区别

const reg = /(a)/g;

reg.exec('a1a'); // ["a", "a", index: 0, input: "a1a", groups: undefined]
'a1a'.match(reg); // ["a", "a"]

当正则表达式含有 g 修饰符时,RegExp.prototype.exec 每次只返回一个匹配结果,数据格式和不含 g 修饰符相同。

String.prototype.match 会返回所有的匹配结果,数据格式会变为字符串数组。

由于 String.prototype.match 返回的数据格式不固定,因此大多数情况都建议使用 RegExp.prototype.exec

lastIndex

RegExp.prototype.lastIndex

const reg = /(a)/g;
const str = 'a1a';

reg.lastIndex; // 0
reg.exec('a1a'); // ["a", "a", index: 0, input: "a1a", groups: undefined]
reg.lastIndex; // 1
reg.exec('a1a'); // ["a", "a", index: 2, input: "a1a", groups: undefined]
reg.lastIndex; // 3
reg.exec('a1a'); // null
reg.lastIndex; // 0

当前正则表达式最后一次匹配成功的结束位置(也就是下一次匹配的开始位置)

注意:lastIndex 不会自己重置,只有当上一次匹配失败才会重置为 0 ,因此,当你需要反复使用同一个正则表达式的时候,请在每次匹配新的字符串之前重置 lastIndex!

replace()、search() 和 split()

String.prototype.replace()、String.prototype.search()、String.prototype.split()

'a1a'.replace(/a/, 'b'); // 'b1a'
'a1a'.replace(/a/g, 'b'); // 'b1b'

'a1a'.search(/a/); // 0
'a1a'.search(/a/g); // 0

'a1a'.split(/a/); // ["", "1", ""]
'a1a'.split(/a/g); // ["", "1", ""]

场景一:正则与数值

/[0-9]+/

[]:字符集,使用连字符 - 表示指定的字符范围,如果想要匹配连字符,需要挨着方括号放置,或进行转义,0-9 表示匹配从 0 到 9 的数字字符,常用的还有 a-z 匹配小写字母,\u4e00-\u9fa5 匹配汉字等,如果只是匹配数字,还可以使用字符集缩写 \d

+:限定符,匹配一个或多个

缺点:不是全字符匹配,包含就会捕获,存在误判,如 /[0-9]+/.test(‘a1’) === true

/^\d+$/

^:匹配字符串开始位置,当结合 m 修饰符时,匹配某一行开始位置

$:匹配字符串结束位置,当结合 m 修饰符时,匹配某一行结束位置

缺点:不能匹配带符号的数值,如 +1,-2,不能匹配小数,如 3.14159

/1?\d+(.\d+)?$/

():圆括号内是一个子表达式,当圆括号不带任何修饰符时,表示同时创建一个捕获组

?:在正则中有多种含义,作为限定符时,表示匹配零到一个

\.:. 可以匹配除换行符之外的任意字符,当结合 s 修饰符时,可以匹配包括换行符在内的任意字符当匹配小数点字符时需要转义

缺点:不能匹配无整数部分的小数,如 .123,捕获组会带来额外的开销

/2?(?:\d*.)?\d+$/

(?:):创建一个非捕获组

* :限定符,匹配零个或多个

缺点:

不能匹配无小数部分的数值,如 2.

不能匹配科学计数法,如 1e2、3e-1、-2.e+4

7 Node.js 基础

概念

Node.js 是一个运行在 V8 的 JavaScript 运行时

Node.js is a JavaScript runtime build on Chrome’s V8

Node.js uses an event-driven, non-blocking I/O model

非阻塞 I/O

阻塞:I/O 时进程休眠等待 I/O 完成后进行下一步

非阻塞:I/O 时函数立即返回,进程不等待 I/O 完成

事件驱动

  • I/O 等待异步操作结束后的通知
  • 观察者模式

与 JavaScript 的区别

  • 基于异步 I/O 相关接口
  • 基于 node_modules 和 require 的模块依赖
  • 提供 C++ addon API 与系统交互

Node.js 基础

运行 node.js

// index.js
console.log('Hello World');

全局安装 node 后,可以在控制台通过node index.js运行

读写文件

通过内置模块fs异步读取

const fs = require('fs');
fs.readFile('test.txt', (err, data) => {
    console.log(data);
});
console.log('read file content');

模块

  • 内置模块:编译进 Node 中,例如 http fs net process path 等
  • 文件模块:build-in 模块之外的模块,和文件夹一一对应

内置模块和文件模块导入时路径书写方式不同,内置模块更为方便

内置模块

const fs = require('fs');
fs.readFile('a.text', (err, buffer) => {
  console.log(buffer);
})

const {readFile} = require('fs');
readFile('a.txt', (err, buffer) => {
  console.log(buffer);
})

文件模块

// app.js
var circle = require('./circle.js');
console.log('半径为4的圆面积是:' + circle.area(4));

定义模块

模块会将exports对象导出,外部可以借此获得模块导出的方法

// circle.js
const pi = Math.PI;
exports.area = function (r) {
    return pi * r * r;
};
exports.circumference = function (r) {
    return 2 * pi * r;
};

模块加载

// 加载绝对路径文件
require('/foo/bar/a.js');

// 加载相对路径文件
require('../a.js');

// 加载无后缀的文件
require('../a');

// 加载外部模块
require('pkg-name');

模块路径查找

  • 绝对路径
  • 相对路径
    • 和当前路径处理为绝对路径
  • 模块/文件夹
    • 原生模块,直接读取缓存
    • [$NODE_PATH, ~/.node_modules,
      ./node_modules, …/node_modules, …]
    • 解析 package.json,查找 main 属性,没有则使用 index.js
    • 如果未找到,则报错

JS 模块解析

// app.js
const circle = require('./circle.js');
  • 通过 fs.readFileSync 同步拿到文件内容
  • 对内容进行包装
(function (exports, require, module, __filename, __dirname) {
    var circle = require('./circle.js');
    console.log('The area is ' + circle.area(4));
});
  • 通过 vm.runInThisContext 执行
  • 获取 module 对象的值作为模块的返回值

vm 是 nodejs 里一个沙盒环境

模块缓存

  • 模块加载后会将返回值缓存起来
  • 下次加载时直接读取缓存结果,避免文件 I/O 和解析时间
  • 导出对象缓存在 Module._cache 对象上

NPM

包管理

  • 一个package.json文件应该存在于包顶级目录下
  • 二进制文件应该包含在bin目录下
  • JavaScript代码应该包含在lib目录下
  • 文档应该在doc目录下
  • 单元测试应该在test目录下

package.json

npm init -y

{
  "name": "star-plan",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Tip: 可以使用 npm config set init.author.name 等命令修改初始化时的默认值

版本号

  • 0.0.1:bug 的修复或补丁的修复
  • 0.1.0:特性的增加
  • 1.0.0:大版本修改,重构,不向后兼容

包依赖

  • 1.0.0 Must match version exactly,准确版本

  • >1.0.0 Must be greater than version

  • >=1.0.0: 大于等于 1.0.0

  • ~1.0.0: “Approximately equivalent to version”,允许小版本更新

  • ^1.0.0: “Compatible with version” ,allow 1.3.1, reject 2.0.0

  • 1.2.x: 1.2.0, 1.2.1, etc., but not 1.3.0

  • *: Matches any version

  • version1 - version2: Same as >=version1 <=version2.

基于 Node.js 开发

const http = require('http');
const server = http.createServer((req, res) => {
  res.end('Hello World');
});
server.listen(3000);

Koa

Koa

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});

app.listen(3000);

Koa 无规范约束,不利于团队开发,中间件繁多,质量参差不齐,选择困难

thinkJS

安装

npm install -g think-cli

RESTful 接口规范

  1. 每个 API 都对应一种资源或资源集合
  2. 使用 HTTP Method 来表示对资源的动作
  3. 使用 HTTP Status Code 来表示资源操作结果

  1. +- ↩︎

  2. +- ↩︎

发布了10 篇原创文章 · 获赞 8 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/pznavbypte/article/details/105444238