前端程序员需要了解的JavaScript之高级部分知识

news/2024/11/8 20:36:12/

前言:这一篇文章主要讲解JavaScript高级的知识,涉及到原型,类,继承,模块化,正则匹配,以及promise的使用,还会了解到一些鼠标键盘事件以及关于前端页面内容的知识。学完这些你可以去学typescript了,加油呀

目录

一:原型:一个对象

原型链:

设置原型链

设置一个对象作为另一个对象的原型:

设置对象的原型:

原型是一个对象:

  

原型链的意义:

合理的构造函数声明:

原型链方法的借用:call等方法

 this不受原型的影响:

不要滥用添加原型方法:

原型链的检测:

原型链的继承:

理解:

类:

类的定义

 类的特点:

类的属性:

静态属性static

静态方法:

 练习demo:

类的属性保护:

类的继承: 

属性和方法的继承:super

super使用规则:

静态static的继承:

类的混合:

类的综合使用:

总结:

怎么使用类的成员方法:

怎么区别是用静态关键字:

模块化:

根据es6的模块化规则:

模块化的特点:

模块作用域:

导出:

具名导出:

默认导出:

导入:

具名导入:

批量导入:

webpack打包:

正则:

用处:

对比:

 创建正则:

字面量形式:

对象形式:

例子:

转义 反斜杠 \:

字符边界

 数值与空白符:

模式修正符:

m 换行demo:

u:

u demo

#lastIndex

 贪婪匹配字符:

贪婪匹配:匹配贪婪字符前一个字符的多个

禁止贪婪:在贪婪匹配的规则后面加?

原子表 [ ]:

原子组 ( ):

引用分组: 

 多个正则校验思路:

正则方法:

exec;检索字符串,还不如用match

test:检索返回布尔值

关于正则的字符串方法:

search:返回索引

match:匹配出符合要求的字符串

matchAll:检索出符合要求的迭代对象,配合全局g使用

split:分割,括号里面可以写正则 

replace:替换方法,常用于字符串的增删改查,配合正则*******

 断言匹配:

Promise: 


一:原型:一个对象

原型洽淡的比喻就是你的父亲,原型链就是家族谱。你可以找你父亲要点什么,你父亲可以找你爷爷要点什么,你在js中普通定义的变量都不是孤儿。

show: ƒ show() 自己原型·:父亲1  服务于实例化的对象,例如使用构造函数生成的实例******重要
[[Prototype]]: Object
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()原型:父亲2 服务于本身这个对象
__proto__: Object
constructor: ƒ Object()
assign: ƒ assign()
create: ƒ create()

你可以调用一些方法,可能你本身没有,所以你去找原型父亲身上看看有没有,有的话就能使用父亲的方法。如果你自己本身有属性方法和父亲有相同的名字的方法,你的优先级更大,因为你有钱了就不会去找父亲要钱。

原型链:

根据原型链的规则,实例对象的-proyo-他是等于构造函数的prototype的

意思就是:每个实例身上都有 __proto__ 属性,它指向构造函数的 Prototype(Prototype这个属性是构造函数身上的属性,它服务于构造函数创造的实例)  。构造函数的  __proto__ 属性 直接指向上层的 Prototype ,最后OBject的 __proto__ 终点为null

设置原型链

设置一个对象作为另一个对象的原型:

使用Object.setPrototypeOf 可设置对象的原型,下面的示例中继承关系为 obj>hd>cms。

Object.getPrototypeOf 用于获取一个对象的原型。

let obj = {name: "后盾人"
};
let hd = {web: "houdunren"
};
let cms = {soft: "hdcms"
};
//让obj继承hd,即设置obj的原型为hd
Object.setPrototypeOf(obj, hd);
Object.setPrototypeOf(hd, cms);
console.log(obj.web);
console.log(Object.getPrototypeOf(hd) == cms); //true

能通过原型上的constructor找到构造函数

 let c = Object.getPrototypeOf(a).constructor 

设置对象的原型:

let user = {show() {return this.name;}
};let hd = Object.create(user); 把user作为hd的原型
hd.name = "向军";
console.log(hd.show());//向军

原型是一个对象:

  

-proto-这个东西其实是getter访问器,设置它的值只能是一个原型对象,因为setter做了限制,如果说你想跳过原型,仅仅只把它当作属性,可以把当前对象的原型去掉

let obj = Object.create(null)//obj没有原型obj._proto_=999//这个就只是个属性了

原型链的意义:

合理的构造函数声明:

构造函数构造对象,不要在构造函数里面写属性方法,容易内存开销,建议写在构造函数的Prototype属性上,提供给对象使用。

   function created(name){this.name =name}created.prototype={constructor:created,show(){console.log(this.name);}}const obj = new created("yy")const obj2 = new created("aa")obj.show()//obj这个对象能使用构造函数原型上的show方法,可以避免构造函数构造对象内存消耗obj2.show()

就是 在父级对象定义方法,他的后代可以继承使用。就方便快捷一点。 

原型链方法的借用:call等方法

理解:比如你家没有车,你去问邻居借

  Math.max.apply(null,arr)  //借用Math对象身上的max属性方法,通过apply改变传过去的对象。

 this不受原型的影响:

  let a = {name: 1,};let b = {name: 2,g() {console.log(this.name);},};Object.setPrototypeOf(a, b);a.g(); //1

不要滥用添加原型方法:

容易冲突! 

原型链的检测:

console.dir(a instanceof A); //true   a继承A构造函数的原型链console.log(b.isPrototypeOf(a)); //true   b是否是a的长辈,就是b下面有a,b的原型链下面有a

原型链的继承:

继承不是构造函数改变属性protype的指向,继承是-proto-原型的继承

理解:

  1. —proto— : 只要是一个对象实例,他就有这个属性去设置自己的原型
  2. —protype— :这个是构造函数身上的属性,他是服务于构造函数的实例,比如在这个属性上添加方法,可以给实例使用,但是构造函数也是个对象,它自己本身也是个对象实例,所以它也可以设置—proto—原型
  3. object.create会重新设置新的原型,而—proto—是改变原来原型的指向

类:

类的typeof其实是一个函数。本质也是一个函数,只是在面向对象编程时更加清晰,相当于原型的语法糖

类的定义

 class User {类的属性,是所有实例对象所公共的属性name='yy';构造函数  加上this则为每个实例对象独享的属性constructor(name) {this.name = name;this.show = function () {};}类的方法,生成的实例对象可以调用,本质是原型protype上的方法,减少内存开销getName() {return this.name;}}
实例对象,自动调用constructor构造函数const xj = new User("向军大叔");console.log(xj);

 

 类的特点:

  • constructor 方法会在 new 时自动执行
  • class定义的类方法在实例对象中不能遍历到
  • 默认严格模式,普通function下的this指向underfined
  • 类的this指向问题,一般来说谁调用了属性方法,this就指向谁

类的属性:

  class User {name = 'yy'}let obj = new User()let obj2 = new User()obj.name = 'qq'  //修改类的属性,不会影响到其他实例console.log('obj', obj) //{name: 'qq'}console.log('obj2', obj2) //{name: 'yy'}

静态属性static

原理:静态属性即为类设置属性,而不是为生成的对象设置

给所有实例对象都能用到,但是不属于实例对象,他的原理是属性class类的属性

  • 可以把为所有对象使用的值,但是 实例对象访问不到该属性    定义为静态属性,
class User {static age = 22;constructor(name) {this.name = name;}getinfo() {return this.name + User.age}}const yy = new User('小鱼');// 静态属性不会给实例对象console.log(yy); // {name: '小鱼'}console.log('User.age', User.age) //22console.log('yy.getinfo()', yy.getinfo())//小鱼22

静态方法:

使用类名调用的方法为静态方法

通过类访问不能使用对象访问的方法,比如系统的Math.round()就是静态方法 

  • 一般来讲方法不需要对象属性参与计算就可以定义为静态方法
  • 不针对单个对象操作
  • 针对多个对象使用,即整个类使用,类去调用
class User {constructor(name) {this.name = name;}static create(name) {return new User(name);}
}通过类名User 调用静态方法create 传参,返回一个构造的实例对象
const xj = User.create("yy");
console.log(xj); {
name:‘yy’
}

 练习demo:

 let peoples = [{name: '邹昀',age: 25},{name: '单龙飞',age: 22},]class Dimine {constructor(info) {this.info = info;}// 适用属性访问器访问info对象的值get agea() {return this.info.age}//获取员工信息static getinfo(allInfo) {return allInfo.map(i => new Dimine(i))}//获取年龄最大的员工信息,该处使用了对象的访问器static getMaxage(v) {return Math.max(...v.map(i => i.agea))}}const message = Dimine.getinfo(peoples)console.dir(message)message的结构[{info: {name: '邹昀',age: 25}}, {info: {name: '单龙飞',age: 22},}]const Maxage = Dimine.getMaxage(message)console.log('Maxage', Maxage) //25

类的属性保护:

1:命名可以使用不一样的风格,比如加个下划线,然后通过访问器进行修改

 _host = "https://houdunren.com";set host(url) {if (!/^https:\/\//i.test(url)) {throw new Error("网址错误");}this._host = url;}

 2:利用semboy或着webpeb设置保护属性

3:private关键字  定义私有属性  简写 #    私有属性只能在当前声明类中使用

类的继承: 

类的方法是在原型链上的,直接可以继承使用,属性是属于实例对象的,需要在构造函数里面使用super

super可以访问父级类

属性和方法的继承:super

class Person {constructor(name) {this.name = name;}show() {return `后盾人会员: ${this.name}`;}
}
class User extends Person {constructor(name) {super(name);}run() {利用super调用父级方法return super.show();}
}
const xj = new User("向军");
console.dir(xj.run());

super使用规则:

  • 子类声明了构造函数,如果继承父类,必须写上super
  • super必须写在子类构造函数this之前,防止父类覆盖子类

子类的方法优先级大于父类 

静态static的继承:

子类可以直接调用父类静态属性

class User {static site = "后盾人";static host() {return "houdunren.com";}}class Admin extends User {}静态属性是通过类去调用console.log('User.site', User.site)//后盾人console.log('Admin.site', Admin.site)//后盾人

类的混合:

使用拷贝将对象拷贝在类的原型上面
Object.assign(Lesson.prototype, Tool);

类的综合使用:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><style>* {padding: 0;margin: 0;box-sizing: content-box;}body {padding: 30px;}.slide {width: 300px;display: flex;flex-direction: column;/* box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3); */}.slide dt {height: 30px;background: #34495e;color: white;display: flex;align-items: center;padding-left: 10px;cursor: pointer;}.slide dt:first-of-type {border-top-left-radius: 10px;border-top-right-radius: 10px;}.slide dd {height: 100px;background: #f1c40f;overflow: hidden;}.slide dd div {padding: 10px;}.slide dd:last-of-type {border-bottom-left-radius: 10px;border-bottom-right-radius: 10px;}</style><body><div class="slide s1"><dt>后盾人</dt><dd><div>houdunren.com</div></dd><dt>后盾人</dt><dd><div>hdcms.com</div></dd><dt>后盾人</dt><dd><div>hdcms.com</div></dd></div>
</body><script>
动画类class Animation {constructor(el) {this.el = el;this.timeout = 5;this.isShow = true;this.defaultHeight = this.height;}hide(callback) {this.isShow = false;let id = setInterval(() => {if (this.height <= 0) {clearInterval(id);callback && callback();return;}this.height = this.height - 1;}, this.timeout);}show(callback) {this.isShow = false;let id = setInterval(() => {if (this.height >= this.defaultHeight) {clearInterval(id);callback && callback();return;}this.height = this.height + 1;}, this.timeout);}get height() {return window.getComputedStyle(this.el).height.slice(0, -2) * 1;}set height(height) {this.el.style.height = height + "px";}}
操作类class Slide {constructor(el) {this.el = document.querySelector(el);this.links = this.el.querySelectorAll("dt");this.panels = [...this.el.querySelectorAll("dd")].map(item => new Panel(item));this.bind();}bind() {this.links.forEach((item, i) => {item.addEventListener("click", () => {this.action(i);});});}action(i) {Panel.hideAll(Panel.filter(this.panels, i), () => {this.panels[i].show();});}}
面板类继承动画类,达到使用动画类的方法class Panel extends Animation {static num = 0;static hideAll(items, callback) {if (Panel.num > 0) return;items.forEach(item => {Panel.num++;item.hide(() => {Panel.num--;});});callback && callback();}static filter(items, i) {return items.filter((item, index) => index != i);}}let hd = new Slide(".s1");console.log('hd', hd)
</script></html>

 上面运用的dom操作,定时器,防抖,数组方法,回调函数,面向对象编程思路

总结:

怎么使用类的成员方法:

1:创建类的实例对象

2:继承父类,子类的实例对象可以使用

怎么区别是用静态关键字:

关于类的使用可以加上static

模块化:

使用模块化能避免一些作用域的问题。

根据es6的模块化规则:

  • 使用export 将开发的接口导出
  • 使用import 导入模块接口
  • 使用*可以导入全部模块接口
  • 如果导入写{}意思是你需要接受多个导出,如果导出只有一个,可以写默认导出。导入就不需要写{}
  • 默认导出只是导出一个的情况,导入可以随便哪个变量名都可以接收,导出导入都不需要花括号!
  • 导出是以引用方式导出,传址。无论是标量还是对象,即模块内部变量发生变化将影响已经导入的变量
  • 别名导入导出,使用as替换
      import { User as user, func as action, site as name } from "./hd.js";let func = "houdunren";
    这个时候下面就需要使用别名console.log(user);console.log(action);console.log(name);
    

模块化的特点:

  1. 严格模式
  2. 只执行一次,预解析
  3. 靠后执行

模块作用域:

类似于函数作用域,拥有独立作用域,且默认拥有严格模式

只有在导出和导入的时候,才能去访问到。两者缺一不可


导出:

export   总共导出一个对象或者单个具名导出

具名导出:

export const site = "后盾人";
export const func = function() {return "is a module function";
};
export class User {show() {console.log("user.show");}
}或者const site = "后盾人";
const func = function() {return "is a module function";
};
class User {show() {console.log("user.show");}
}
export { site, func, User };

默认导出:

只有一个需要导出时,可以设置默认导出

导出:不需要写{}
export default class User  {static show() {console.log("User.method");}
}导入:也不需要{},同时变量可以随意定义,就代表导出的那个内容import User from "./hd.js";

导入:

import  导入一个对象  from   “路劲”

具名导入:

 import { User, site, func } from "./hd.js";

批量导入:

使用api这个变量来全部批量导入,缺点:不需要的你都导入进来了,显得臃肿效率低

 import * as api from "./hd.js";api这个对象去找下面的属性console.log(api.site);console.log(api.User);

webpack打包:

将文件打包到dist目录下面。


正则:

 用处是对字符串的增删改查!,操作字符串优先考虑正则,字符串的方法很多可以使用正则

用处:

  • 用在字符串replace替换,font.replace(//,"")
  • 用在字符串校验是否含有该元素,(//.test(font))返回布尔值
  • 查找符合条件的字符串,拿出来font.match(reg)

对比:

常规:
let hd = "houdunren2200hdcms9988";
解构语法转为数组,利用判断是不是转换为数字类型然后实行数组过滤
let nums = [...hd].filter(a => !Number.isNaN(parseInt(a)));
console.log(nums.join(""));正则:
let hd = "houdunren2200hdcms9988";
console.log(hd.match(/\d/g).join(""));

 创建正则:

字面量形式:

使用//包裹的字面量创建方式是推荐的作法,但它不能在其中使用变量

let hd = "houdunren.com";
console.log(/u/.test(hd));//true

对象形式:

当正则需要动态创建时使用对象方式

let hd = "houdunren.com";
let web = "houdunren";
let reg = new RegExp(web);
console.log(reg.test(hd)); //true

例子:

<body><div id="yy">今天是2022年</div>
</body><script>const enter = prompt('请输入要搜索的内容,支持正则表达式')// 创建字符串规则let zz = new RegExp(enter, 'g')let doc = document.querySelector('#yy')doc.innerHTML = doc.innerHTML.replace(zz, search => {return `<span style='color:red'>${search}</span>`})
</script>

转义 反斜杠 \:

利用\ 后加特殊字符实现转义。

字符边界

使用字符边界符用于控制匹配内容的开始与结束约定。

边界符说明
^匹配字符串的开始
$匹配字符串的结束,忽略换行符
const hd = "www.houdunren.com";
console.log(/^www/.test(hd)); //true例子:<body><input type="text"><span></span>
</body><script>const input = document.querySelector('input');input.addEventListener('keyup', function () {let flag = this.value.match(/^[a-z]{3,6}$/)document.querySelector('span').innerHTML = flag ? '正确' : '失败'})
</script>

 数值与空白符:

最基础的匹配字符。


元字符说明示例
\d匹配任意一个数字[0-9]
\D与除了数字以外的任何一个字符匹配[^0-9]
\w与任意一个英文字母,数字或下划线匹配[a-zA-Z_]
\W除了字母,数字或下划线外与任何字符匹配[^a-za-z_]
\s任意一个空白字符匹配,如空格,制表符\t,换行符\n[\n\f\r\t\v]
\S除了空白符外任意一个字符匹配[^\n\f\r\t\v]
.匹配除换行符外的任意字符

 大写的一般为 除了


模式修正符:

修饰符说明
i不区分大小写字母的匹配
g全局搜索所有匹配内容
m视为多行
s视为单行忽略换行符,使用. 可以匹配所有字符
y从 regexp.lastIndex 开始匹配,注意他会连续匹配,如果匹配不符合连续,则匹配结束
u正确处理四个字符的 UTF-16 编码,用来处理汉字或者全局大的匹配

m 换行demo:

 let hd = `#1 js,200元 ##2 php,300元 ##9 houdunren.com # 后盾人#3 node.js,180元 #
`;let lessons = hd.match(/^\s*#\d+\s+.+\s+#$/gm).map(i => {[Lname, price] = i.replace(/\s*#\d+\s+/, '').replace(/\s+#/, '').split(',')return {Lname,price}})console.log('lessons', lessons)

u:

可以考虑用来匹配字母或者标点 或者中文

u demo

每个字符都有属性,如L属性表示是字母,P 表示标点符号,需要结合 u 模式才有效。其他属性简写可以访问 属性的别名 (opens new window)网站查看。

使用\p{L}属性匹配字母
let hd = "houdunren2010.不断发布教程,加油!";
console.log(hd.match(/\p{L}+/u));使用\p{P}属性匹配标点
console.log(hd.match(/\p{P}+/gu));

字符也有 unicode 文字系统属性 Script=文字系统,下面是使用 \p{sc=Han} 获取中文字符 han为中文系统,其他语言请查看 文字语言表(opens new window)

let hd = `
张三:010-99999999,李四:020-88888888`;
let res = hd.match(/\p{sc=Han}+/gu);
console.log(res);['张三', '李四']

使用 u 模式可以正确处理四个字符的 UTF-16 字节编码

let str = "𝒳𝒴";
console.table(str.match(/[𝒳𝒴]/)); //结果为乱字符"�"console.table(str.match(/[𝒳𝒴]/u)); //结果正确 "𝒳"

#lastIndex

RegExp 对象lastIndex 属性可以返回或者设置正则表达式开始匹配的位置

  • 必须结合 g 修饰符使用
  • 对 exec 方法有效
  • 匹配完成时,lastIndex 会被重置为 0
let hd = `后盾人不断分享视频教程,后盾人网址是 houdunren.com`;
let reg = /后盾人(.{2})/g;
reg.lastIndex = 10; //从索引10开始搜索
console.log(reg.exec(hd));
console.log(reg.lastIndex);reg = /\p{sc=Han}/gu;
while ((res = reg.exec(hd))) {console.log(res[0]);
}

 贪婪匹配字符:

贪婪匹配:匹配贪婪字符前一个字符的多个

+:一个或多个(贪婪),贪婪的放在一起

*:表示0个或多个

{}:花括号里面表示匹配几个,逗号相隔是几到几。逗号后面参数不写,表示无数。

?:问号代表0个或一个。表示存不存在。

匹配所有字符可以使用原子表 [\s\S] 或 [\d\D] 

贪婪匹配符号说明
*表示0个或多个
+一个或多个(贪婪),贪婪的放在一起
?重复零次或一次
{n}重复 n 次
{n,}重复 n 次或更多次
{n,m}重复 n 到 m 次

禁止贪婪:在贪婪匹配的规则后面加?

尽可能的减少贪婪。往最低下限验证规则。比如*是0到多个,*?趋向0个

说明白点,就是禁止了你的贪婪。

let str = "aaa";
console.log(str.match(/a+/)); //aaa
console.log(str.match(/a+?/)); //a
console.log(str.match(/a{2,3}?/)); //aa
console.log(str.match(/a{2,}?/)); //aalet str = 'yu'let reg = /yu*?/gi;console.log('str.match(reg)', str.match(reg))//['y']


原子表 [ ]:

原子表说明
[]只匹配其中的一个原子
[^]只匹配"除了"其中字符的任意一个原子
[0-9]匹配 0-9 任何一个数字
[a-z]匹配小写 a-z 任何一个字母
[A-Z]匹配大写 A-Z 任何一个字母

[]:原子表,里面写的东西算包含(可选的意思),加上^表示 除了

【】内不解析字符含义,点只代表点的意思。也不需要转义


原子组 ( ):

  • 如果一次要匹配多个元子,可以通过元子组完成
  • 原子组与原子表的差别在于原子组一次匹配多个元子,而原子表则是匹配任意一个字符
  • 元字符组用 () 包裹,表示一个整体,就类似的概念

|:表示或,配合原子组()一起使用 

引用分组: 

\n 在匹配时引用原子组,例如\1,\2。

下面使用原子组匹配 h1 标签,如果想匹配 h2 只需要把前面原子组改为 h2 即可。

const hd = `<h1>houdunren.com</h1>`;
console.log(/<(h1)>.+<\/\1>/.test(hd)); //true

$n 指在替换时使用匹配的组数据。

let hd = `<h1>houdunren</h1><span>后盾人</span><h2>hdcms</h2>
`;let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi;
console.log(hd.replace(reg, `<p>$2</p>`));

 多个正则校验思路:

将正则规则写成数组,利用数组的every方法进行子项的正则的test方法,返回布尔值。

<body>
<input type="text" name="password" />
</body>
<script>
let input = document.querySelector(`[name="password"]`);
input.addEventListener("keyup", e => {const value = e.target.value.trim();const regs = [/^[a-zA-Z0-9]{5,10}$/, /[A-Z]/];let state = regs.every(v => v.test(value));console.log(state ? "正确!" : "密码必须包含大写字母并在5~10位之间");
});
</script>

正则方法:

exec;检索字符串,还不如用match

reg.exec(str)

  let s = 'yuu'如果不加g,和match一样,拿出来的是详细信息
加了g以后,要配合while循环才能拿到下一个匹配字符
这里没写while循环,所以结果一样let reg = /u/gconsole.log('reg.exec(s)', reg.exec(s))  ['u', index: 1, input: 'yuu', groups: undefined]

test:检索返回布尔值

reg.test(str)


关于正则的字符串方法:

search:返回索引

寻找符合要求的字符串,返回索引,没有的话为-1,还不如include方法,括号里面可以写正则

match:匹配符合要求的字符串

如果正则语法加了全局修饰符g,则匹配出来的不会有详细信息,返回是一个数组。想要有详细信息使用matchall

let hd = "houdunren";
let res = hd.match(/u/);
console.log(res);  一段数组,详细信息['u', index: 2, input: 'houdunren', groups: undefined]
console.log(res[0]); //匹配的结果
console.log(res[index]); //出现的位置let hd = "houdunren";加全局g let res = hd.match(/u/g);console.log(res);['u', 'u']

matchAll:检索出符合要求的迭代对象,配合全局g使用

全局匹配:返回的是一个正则迭代数组集,里面是每个详细信息。可以遍历。

 let str = "houdunren";let reg = /[a-z]/ig;let arr = []for (const iterator of str.matchAll(reg)) {// console.log(iterator);arr.push(iterator[0])}console.log('arr', arr)

split:分割,括号里面可以写正则 

let str = "2023/02-12";
console.log(str.split(/-|\//));

replace:替换方法,常用于字符串的增删改查,配合正则*******

常用的字符串替换。对字符串进行增删改查优先考虑这个替换方法,找到替换元素直接改成想要的格式。

简单用法

  let str = "2023/02-12";str = str.replace(/\/|-/g, "")console.log('str', str)在字符串的后面加东西let hd = "(010)99999999 (020)8888888";hd = hd.replace(/\)/g, ')-')console.log('hd', hd)  (010)-99999999 (020)-8888888在字符串的后面加东西let hd = "(010)99999999 (020)8888888";使用替换特殊变量名,$&代表匹配出的字符本身,下面有介绍hd = hd.replace(/\)/g, '$&-')console.log('hd', hd) 结果一样

 复杂用法

1:替换字符串可以插入下面的特殊变量名:不需要回调函数的形式

变量说明
$$插入一个 "$"。
$&插入匹配的子串。有用,可以直接拿到正则匹配的字符串
$`插入当前匹配的子串左边的内容。
$'插入当前匹配的子串右边的内容。
$n假如第一个参数是 RegExp 对象,并且 n 是个小于 100 的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从 1 开始,配和正则的原子组使用
在后盾人前后添加三个=let hd = "=后盾人=";
console.log(hd.replace(/后盾人/g, "$`$`$&$'$'"));
把电话号用 - 连接let hd = "(010)99999999 (020)8888888";
console.log(hd.replace(/\((\d{3,4})\)(\d{7,8})/g, "$1-$2"));
把所有教育汉字加上链接 https://www.houdunren.com<body>在线教育是一种高效的学习方式,教育是一生的事业
</body>
<script>const body = document.body;body.innerHTML = body.innerHTML.replace(/教育/g,`<a href="https://www.houdunren.com">$&</a>`);
</script>

 2:replace方法的第二个参数可以是一个回调函数

replace 支持回调函数操作,用于处理复杂的替换逻辑

回调函数接受的参数。参数顺序排名

  1. 匹配到的字符
  2. 原子组的排序(有几个就排到几个,比如两个,参数用到就占有两个,p1,p2)
  3. 位置,很少用到
  4. 原字符串

变量名代表的值
match匹配的子串。(对应于上述的$&。)
p1,p2, ...假如 replace()方法的第一个参数是一个 RegExp 对象,则代表第 n 个括号匹配的字符串。(对应于上述的$1,$2 等。)例如,如果是用 /(\a+)(\b+)/ 这个来匹配,p1 就是匹配的 \a+p2 就是匹配的 \b+
offset匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc',那么这个参数将会是 1)
string被匹配的原字符串。
NamedCaptureGroup命名捕获组匹配的对象

用途操作html中的文本标签内容 

 替换页面的内容标签

  const reg = /<(h[1-6])>(.*?)<\/\1>/g;const body = document.body.innerHTML;const html = body.replace(reg, function (str, tag, content) {console.log('str', str) //匹配出的字符串console.log('tag', tag) //标签  其实是第一个原子组console.log('content', content) //内容  其实是第二个原子组return `<p>${content}</p>`;  模板字符串的写法});document.body.innerHTML = html;完整用法let content = document.querySelector(".content");let reg = /<(h[1-6])>([\s\S]*?)<\/\1>/gi;content.innerHTML = content.innerHTML.replace(reg,(search, //匹配到的字符p1, //第一个原子组p2, //第二个原子组index, //索引位置source //原字符) => {return `<${p1} class="hot">${p2}</${p1}>`;});


 断言匹配:

为正则的前后加上判断条件,相当于弄了一层约束,更精准


Promise: 

关于promise的内容单独放了一篇文章

Promise的异步同步问题_成为前端大牛的博客-CSDN博客_promise异步转同步


http://www.ppmy.cn/news/428305.html

相关文章

IDEA+Java+Servlet+JSP+Mysql实现Web停车场管理系统【建议收藏】

目录 一、系统介绍 1.开发环境 2.技术选型 3.系统功能 4.数据库 5.工程截图 二、系统展示 1.登录界面 2.主页面 3.系统信息管理-添加角色信息 4.系统信息管理-管理角色信息 5.系统信息管理-添加用户信息 6.系统信息管理-管理用户信息 7.车位信息管理-添加车位信息…

实时采样与等效采样

实时采样与等效采样 基本的数字化采样方式有两种&#xff1a;实时采样与等效采样 实时采样 实时采样&#xff1a;以等时间间隔的方式&#xff0c;且按时间的顺序&#xff0c;对波形进行A/D转换&#xff0c;并进行存储。如图。 实时采样是最直观的采样方式&#xff0c;其只…

题目记录:

无重复字符的最长子串 class Solution:def lengthOfLongestSubstring(self, s: str) -> int:if not s:return 0 #判断是否为空left 0lookup set() # set() 函数创建一个无序不重复元素集n len(s) # 字符串长度max_len 0 # 最大长度cur_len 0 # 滑动框长度for i in r…

Django3(二)异步编程

目录 一、使用多线程 二、启用ASGI服务 三、异步视图 异步与同步的转换 其他&#xff1a;消息队列(基本概念) 异步编程&#xff1a;使用协程、线程、进程、消息队列等方式实现。 Django支持多线程、内置异步和消息队列方式实现。 多线程&#xff1a;在当前运行的Django服务…

Markdown语法案例

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

秘密的爱:初窥RSA非对称加密算法

hello,everybody! 来一个迟到的七夕祝福! 场景: 假设李雷和韩梅梅生活在1984一样的一个极权世界,七夕到了,李雷想向韩梅梅表达爱意.但是他又不能以明文给韩梅梅传递这个信息.要不big brother就会打爆他的头.因为法律这玩意儿可怕哟! 问题: 如何通过加密传递 I love you! 或者…

【PostgreSQL】GIN索引安装与使用 - 全模糊匹配/数组匹配,PG批量插入上万随机生成数据,随机生成字符串/数组

目录 环境拓展库安装生成随机假数据查询使用GIN索引GIN索引使用条件参考 环境 PostgreSQL DBeaver 拓展库安装 打开SQL编辑器&#xff1a; 输入命令运行即可&#xff1a; CREATE EXTENSION pg_trgm;CREATE extension btree_gin;&#xff08;光标选中某行后&#xff0c;按c…

PTA武林盟主

在传说中的江湖中&#xff0c;各大帮派要选武林盟主了&#xff0c;如果龙飞能得到超过一半的帮派的支持就可以当选&#xff0c;而每个帮派的结果又是由该帮派帮众投票产生的&#xff0c;如果某个帮派超过一半的帮众支持龙飞&#xff0c;则他将赢得该帮派的支持。现在给出每个帮…