1,递归

递归函数:一个函数在内部可以调用其本身

function func() {func()
}
func()


递归容易发生栈溢出错误(stack overflow),以上是一个典型的栈溢出,所以我们必须加退出条件 return

var num = 1
function func() {console.log(`打印${num}次`)if (num === 10) {return}num++func()
}
func()

递归实例:

  • 1, 利用递归求 1 ~ n 的阶乘
function func(n) {// 1 * 2 * 3 * ...nif (n === 1) return 1;return n * func(n - 1)
}
func(5)  // 120
  • 2, // 斐波那契数列(兔子序列):前两项的和等于第三项的值 表现: 1、1、2、3、5、8、13、21、34…
// 用户输入一个数字 n, 求出这个数字对应的兔子序列值
function fb (n) {if (n === 1 || n === 2) return 1return fb(n - 1) + fb(n - 2)
}
fb(9)  // 34
  • 3, 根据 id 返回对应的数据对象
const arr = [{id: 1,name: 'Jerry',friends: [{id: 11,name: 'Lise'},{id: 12,name: 'Tom'}]},{id: 2,name: 'xiaowang'}
];const arr = [{id: 1,name: 'Jerry',friends: [{id: 11,name: 'Lise'},{id: 12,name: 'Tom'}]},{id: 2,name: 'xiaowang'}
];
function getId(data, id) {var o = {}data.forEach(function (value) {if (value.id === id) {o = valuereturn value} else if (value.friends?.length > 0) {o = getId(value.friends, id)}})return o
}
console.log(getId(arr, 12)) // {id: 12, name: 'Tom'}
或者
function getId(arr, id) {let queue = [];arr.forEach(item => {queue.push(item)})while(queue.length > 0) {const value = queue.shift();if(value.id === id) return value;if(value.friends && value.friends.length > 0) {value.friends.forEach(item => queue.push(item));}}
}
console.log(getId(arr, 12)) // {id: 12, name: 'Tom'}

2,深浅拷贝

  • 1,浅拷贝只是拷贝一层,更深层对象级别的只拷贝引用
  • 2,深拷贝拷贝多层,每一级别的数据都会拷贝

浅拷贝

const obj = {name: 'Jerry',age: 18,friends: {name: 'Lise'}
};
var o = {}for (var i in obj) { // i 属性名,obj[i] 属性值o[i] = obj[i]
}
或
Object.assign(o, obj)  // ES6新增的方法可以实现浅拷贝o.friends.name = 'Tom'
console.log(o)
console.log(obj)


深拷贝

const obj = {name: 'Jerry',age: 18,friends: {name: 'Lise'},colors: ['red', 'green', 'blue']
};
var o = {}
// 封装函数
function deepCopy(newObj, oldObj) {for(var i in oldObj) {// 判断属性值是简单数据类型还是复杂数据类型// 1,获取属性值 oldObj[i]const item = oldObj[i]// 2, 判断这个值是否是数组if (item instanceof Array) {newObj[i] = []deepCopy(newObj[i], item)} else if (item instanceof Object) {// 3,判断这个值是否是对象newObj[i] = {}deepCopy(newObj[i], item)} else {// 4,属于基本数据类型newObj[i] = item}}
}
deepCopy(o, obj)

3,正则表达式

正则表达式:用于匹配字符串中字符组合的模式,在JS中,正则表达式也是对象。

通常用于检测、替换那些符合某个模式的文本,例如验证表单:用户名表单只能输入英文字母、数字或者下划线。

还常用于过滤页面内容中的一些敏感词(替换),或者从字符串中获取我们想要的特定部分等

3.1,创建正则表达式

  • 创建正则表达式:

    • 1, 利用 RegExp 对象来创建
    const rg = new RegExp(/表达式/)
    
    • 2, 利用字面量创建正则表达式
    const rg = /表达式/
    
  • 测试正则表达式 test
    test()正则对象的方法,用于检测字符串是否符合该规范,该对象会返回 truefalse
const rg =  /123/
rg.test(123) // true
rg.test(456) // false
  • 正则的组成
    一个正则可以由简单的字符组成,比如/abc/,也可以是简单和特殊字符的组合,比如/ab*c/,特殊字符有叫元字符,在正则中具有特殊意义的专用符号,比如: ^、$、+等

特殊符号可以参考:MDN正则表达式

正则测试工具:https://tool.oschina.net/regex

3.2,正则中的特殊字符

  • 3.2.1 边界符
    正则中的边界符(位置符)用来提示字符串所处的位置,主要有两个:^、$

    • ^ 匹配行首的文本
    • $ 匹配行尾的文本
const rg =  /abc/ // /abc/表示只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc')) // true
console.log(rg.test('abcd')) // true
console.log(rg.test('aabc')) // trueconst reg = /^abc/ // 表示必须以abc开头的
console.log(reg.test('abc')) // true
console.log(reg.test('abcd')) // true
console.log(reg.test('aabc')) // false
console.log(reg.test('abdc')) // falseconst reg1 = /^abc$/ // 精确匹配
console.log(reg1.test('abc')) // true
console.log(reg1.test('abcd')) // false
console.log(reg1.test('aabc')) // false
  • 3.2.2 字符类:[]
    表示有一系列字符可供选择,只要匹配其中一个就可以了
const reg = /[abc]/  // 表示只要包含有a 或 有b 或 有c,都返回true
console.log(reg.test('alia')) // trueconst reg1 = /^[abc]$/  // 表示只有是a 或 b 或 c,才返回true
console.log(reg1.test('alia')) // false
console.log(reg1.test('a')) // true
console.log(reg1.test('b')) // true
console.log(reg1.test('bc')) // false
console.log(reg1.test('c')) // true
console.log(reg1.test('cc')) // false
console.log(reg1.test('abc')) // false
  • 3.3.3 [-]方括号内 范围符 -
const reg = /^[a-z]$/ // 26个英文字母任何一个字母返回true
console.log(reg.test('alia')) // false
console.log(reg.test('a')) // true
console.log(reg.test('A')) // false
  • 3.3.4 字符组合
// 字符组合
const reg1 = /^[a-zA-Z]$/ // // 26个英文字母(大小写都可以) 任何 一个字母返回true
console.log(reg1.test('alia')) // false
console.log(reg1.test('a')) // true
console.log(reg1.test('A')) // true// 比如:reg = /^[a-zA-Z0-9_-]$/
  • 3.4.5 []方括号内 表示取反
const reg = /^[^abc]$/
console.log(reg.test('a'))  // false
  • 3.4.6 量词符

用来设定某个模式出现的次数

量词 说明
* 重复0次或更多次
+ 重复1次或更多次
? 重复0次或1次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
// *  >= 0
const reg = /^a*$/
console.log(reg.test('')) // true
console.log(reg.test('a')) // true
console.log(reg.test('b')) // false
console.log(reg.test('aaa')) // true// + >= 1
const reg1 = /^a+$/
console.log(reg1.test('')) // false
console.log(reg1.test('a')) // true
console.log(reg1.test('b')) // false
console.log(reg1.test('aaa')) // true// ? 1 || 0
const reg2 = /^a?$/
console.log(reg2.test('')) // true
console.log(reg2.test('a')) // true
console.log(reg2.test('b')) // false
console.log(reg2.test('aaa')) // false// {3} 重复3次
const reg3 = /^a{3}$/
console.log(reg3.test('')) // false
console.log(reg3.test('a')) // false
console.log(reg3.test('b')) // false
console.log(reg3.test('aaa')) // true// {3,} >= 3
const reg4 = /^a{3,}$/
console.log(reg4.test('')) // false
console.log(reg4.test('a')) // false
console.log(reg4.test('b')) // false
console.log(reg4.test('aaa')) // true
console.log(reg4.test('aaaaa')) // true
console.log(reg4.test('aaabc')) // false
console.log('-----------')
// {3,8}  >= 3 && <= 8
const reg5 = /^a{3,8}$/
console.log(reg5.test('')) // false
console.log(reg5.test('a')) // false
console.log(reg5.test('b')) // false
console.log(reg5.test('aaa')) // true
console.log(reg5.test('aaaaa')) // true
console.log(reg5.test('aaabc')) // false
console.log(reg5.test('aaaaaaaa')) // true
  • 3.4.7
// 量词是设定某个模式出现的次数
var reg = /^[a-zA-Z0-9_-]$/ // 这个模式用户只能输入英文字母 数字 下划线 短横线但是有边界符和[] 这就限定了只能多选1
console.log(reg.test('a')) // true
console.log(reg.test('ab')) // false
console.log(reg.test(1)) // true
console.log(reg.test('11')) // false
console.log(reg.test('aa')) // false

4, 正则案例

1, 用户名验证,如果用户名输入合法,提示信息为:用户名合法,颜色改为绿色,如果不合法,则后面提示:用户名不符合规范,改色改为红色

const name = document.querySelector('.name');
const span = document.querySelector('span');
var reg = /^[a-zA-Z0-9_-]{6,16}$/
name.onblur = function () {if (reg.test(this.value)) {span.className = 'green'span.innerHTML = '用户名合法'} else {span.className = 'red'span.innerHTML = '用户名不符合规范'}
}

5, 括号总结

  • 1,量词符大括号,表示重复次数
  • 2,字符集合中括号,匹配方括号中的任意字符
  • 3,小括号,表示优先级
// 中括号[],字符集合,匹配方括号中的任意字符
const reg = /^[abc]$/ // a || b || c都可以// 大括号{},量词符,表示重复次数
const reg1 = /^[abc]{3}$/
console.log(reg1.test('aaa')) // true
console.log(reg1.test('abcabcabc')) // falseconst reg2 = /^abc{3}$/  // 它只是让c重复3次 abccc
console.log(reg2.test('aaa')) // false
console.log(reg2.test('abcabcabc')) // false
console.log(reg2.test('bbb')) // false
console.log(reg2.test('ccc')) // false
console.log(reg2.test('abccc')) // true
console.log(reg2.test('aabccc')) // false// 小括号 表示优先级
const reg3 = /^(abc){3}$/ // 表示让 abc重复3次
console.log(reg3.test('aaa')) // false
console.log(reg3.test('abcabcabc')) // true
console.log(reg3.test('abccc')) // false

6,可以在线测试自己写的正则对不对(https://c.runoob.com/front-end/854/)

也会有一些常用的正则:

7,预定义类

指的是某些常见模式的简写方式

预定义类 说明
\d 匹配0-9之间的任一数字, 相当于[0-9]
\D 匹配所有0-9以外的字符, 相当于[^0-9]
\w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
\W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
\s 匹配空格(包括换行符、制表符、空格符),相当于[\t\r\n\v\f]
\S 匹配非空格的字符,相当于[^\t\r\n\v\f]

实例:

//  座机号码验证:全国座机号码,两种格式:010-12345678 或者 0530-1234567
// const reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/  // 正则里的 或 用 | 表示
// 简写
const reg = /^\d{3,4}-\d{7,8}$/
console.log(reg.test('魑魅魍魉')) // false
console.log(reg.test('3829889')) // false
console.log(reg.test('3829-889')) // false
console.log(reg.test('022-31231321')) // true

8, replace 替换

replace()方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则

// 语法
str.replace(/str/, replacement)
// 第一个参数:被替换的字符串 或者 正则
// 第二个参数:替换为的字符串
// 返回值是一个替换完的新字符串
const str = 'JerryLise'
const newStr = str.replace('Jerry', 'xiaowang')
const newStr = str.replace(/Jerry/, 'xiaowang')
console.log(newStr)  // xiaowangLise

实例:

const text = document.querySelector('textarea')
const btn = document.querySelector('button')
const div = document.querySelector('div')
btn.onclick = function () {div.innerHTML = text.value.replace(/小猫咪/, '**')
}

以上代码replace只能替换第一个满足条件的字符串,后面的就不再替换了,那么我们可以用正则表达式参数

9,正则表达式参数

/表达式/[switch]
// switch也称修饰符,按照什么样的模式来匹配,有三种值:
// 1,g: 全局匹配
// 2,i:忽略大小写
// 3,gi:全局匹配 + 忽略大小写

以上实例:

div.innerHTML = text.value.replace(/小猫咪|超/g, '**')

看完必会的正则表达式和递归相关推荐

  1. 平安京s9服务器维护,平安京S9的细节改动,看完必上分

    原标题:平安京S9的细节改动,看完必上分 就在前几天,决战平安京迎来了S9赛季,同时也迎来了巨大的改动.下面就由小编来带领大家解读S9. 首先,是我们的经济和经验来源兵线和野怪的改动,野怪血量增加了, ...

  2. 00018计算机应用基础怎样过,自学考试公共课00018计算机应用基础(看完必过).doc...

    Page PAGE1 of NUMPAGES34. 自考公共课00018 计算机应用基础(看完必过) 计算机应用基础精髓总结 第1章计算机基础知识 1.计算机的发展和应用[选择](06年下1)计算机发 ...

  3. 自考计算机基础00018难吗,自考公共课00018-计算机应用基础(看完必过).doc

    自考公共课00018 计算机使用基础(看完必过) 计算机使用基础精髓总结 第1章计算机基础知识 1.计算机的发展和使用[选择](06年下1)计算机发展阶段是按照计算机硬件来划分的,大致可分为四个阶段: ...

  4. java递归看回文,如何使用正则表达式实现递归回文检查器? [关闭]

    如果我理解正确,你想在Java中创建一个使用正则表达式的递归回文检查器 . 我对学习Java感兴趣,所以我把它作为我自己的"家庭作业问题",但它也可能是你的 . import ja ...

  5. keil5的安装详解(看完必会,不会你打我)

    如何安装KEIL5 本内容所涉及的软件只供教学使用,不得用于商业用途.个人或公司因商业用途导致的法律责任,后果自负. 温馨提示 1.安装路径不能带中文,必须是英文路径 2.安装目录不能跟51的KEIL ...

  6. 14年的面试官经验分享,看完必有收获

    面试,是找到好工作的过程中,最最重要的一环. 在我14年的职业生涯中,亲自面试的人应该不下1000人了. 看过的简历还要更多,尤其是微软上海早期扩张的时候. 所以今天,我就从自身经历出发,给你分享一些 ...

  7. MOS管的工作原理及常见的封装(看完必会)

    MOS管的工作原理及常见的封装目录 MOS管的概述 MOS管的性能 MOS管的管脚及常见封装识别 MOS管的导通条件 加强理解MOS管 Question? 致谢 MOS管的概述 场效应管(FET),把 ...

  8. java开发小程序好吗,看完必懂

    1关于MySQL,面试官会问哪些问题? 第一个:MySQ性能优化最佳实践21个(有具体的解释)你知道哪些? 为查询缓存优化你的查询 EXPLAIN你的SELECT查询 当只要一行数据时使用LIMIT ...

  9. pythone二级题库 + 刷题软件 (超详细解析,看完必过) 第十一套

    刷题软件(模拟python二级考试) 操作题刷题软件 1.计算机完成一条指令所花费的时间称为一个(). A.指令周期 B.存取周期 C.执行速度 D.执行时序 一般把计算机完成一条指令所花费的时间统称 ...

  10. 电商零售业怎么做数据分析?这10篇作品看完必会

    在2021帆软BI可视化夏季挑战赛中,我们看到了非常多的优秀BI可视化分析作品.其中,零售/电商类的作品尤为丰富,今天帆软君为大家精选出10份优秀作品,希望能够给零售/电商的朋友们带来一些启发: 1. ...

最新文章

  1. glusterfs4.0.1 mempool 分析笔记
  2. 南京人工智能高等研究院孔慧:多向技术驱动,让企业具备长久竞争力
  3. redis(9)--数据库
  4. 【git学习】统计git项目某user的代码量
  5. 中国半导体蚀刻设备行业市场供需与战略研究报告
  6. java.io.IOException: CreateProcess error=2, ?????????
  7. ant 使用java 运行类_用ANT构建java可执行程序
  8. linux远程配置ssh服务,Linux远程服务之OpenSSH配置
  9. [笔记]C++代码演示SingletonMap 单类Map实例
  10. 幼儿-综合素质【1】
  11. office 论文 页码_毕业论文页码格式word操作
  12. 【双轨公排】小公排+推荐奖+对碰奖+层碰奖+见点奖源码系统 演示网站介绍
  13. 手把手带你Yolov5 (v6.x)添加注意力机制(一)(并附上30多种顶会Attention原理图)(新增8种)
  14. 相濡以沫,不如相忘于江湖...
  15. 消失的网秦:创始人遭绑架 414 天,睡觉都戴手铐
  16. resultful风格接口
  17. 区块链报错3 | truffle unbox 报错 | downloading失败 | unbox failed
  18. 2021年塔式起重机司机考试及塔式起重机司机复审考试
  19. 分享高压超低噪声LDO测试结果(High Voltage Ultra-low Noise LDO)
  20. Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk

热门文章

  1. Radiology:磁共振血管造影(MRA)在脑转移瘤治疗中对血管形态改变的测量
  2. 风口下的追逐:AI正在驾驶、客服、教育领域疾驰
  3. mysql数据库安全开关_对MySQL数据库的安全进行的详述
  4. 学硕上几年学计算机,研究生一般要读几年毕业
  5. android数据格式化,手机格式化了?教你找回安卓手机数据
  6. 台风怎么看内存颗粒_《CY》又一4000+的颗粒,三星新版D-DIE颗粒超频测试
  7. Linux系统 查看 Vendor id 和Device id
  8. Android多分辨率适配框架(1)— 核心基础
  9. 锐龙r75800u参数 r7 5800u怎么样
  10. unixbench跑服务器性能,UnixBench 5.1.3性能测试_IntelCPU_服务器评测与技术-中关村在线...