正则表达式
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。 正则表达式在JavaScript中的使用场景:
例如验证表单:用户名表单只能输入英文字母、数字或者下划线,昵称输入框中可以输入中文。 比如用户名: /^[a-z0-9_-]{3,16}$/ 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等。
JavaScript 中定义正则表达式的语法有两种:
1.定义正则表达式语法:
const 变量名=/表达式/
其中//是正则表达式字面量 比如: const reg =/前端/
2.判断是否有符合规则的字符串:
test() 方法用来查看正则表达式与指定的字符串是否匹配语法: reg0bj.test(被检测的字符串)
比如:
// 要检测的字符串 const str = '前端开发" // 1.定义正则表达式,检测规则 const reg =/前端/ // 2.检测方法 console.log(reg.test(str)) // true
如果正则表达式与指定的字符串匹配,返回true,否则false
3.检索(查找)符合规则的字符串:
exec() 方法在一个指定字符串中执行一个搜索匹配语法: reg0bj.exec(被检测字符串) 比如:
//要检测的字符串 const str ='IT培训,前端开发' //1.定义正则表达式,检测规则 const reg =/前端/ //2.检测方法 console.log(reg.exec(str)) // 返回的是数组 [前端",index:5,input:'IT培训,前端开发",groups: undefined]//index:5下表为5时查找到。
如果匹配成功,exec()方法返回一个数组,否则返回null
元字符
边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
如果^和$在一起,表示必须是精确匹配。
量词
量词用来 设定某个模式出现的次数
量词 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
注意:逗号左右两侧千万不要出现空格。
console.log(/^哈?$/.test(' ' )) // true console.log(/^哈?$/.test('哈')) // true console.log(/^哈?$/.test('哈哈')) // false console.log(/^哈?$/.test('二哈很傻')) // false console.log(/^哈?$/.test('哈很傻')) // false console.log(/^哈?$/.test('哈很哈')) // false
重复词只能为要求的词,不能出现其它词。
字符类
[]匹配字符集合 后面的字符串只要包含 abc 中任意一个字符,都返回true 。
// 只要中括号里面的任意字符出现都返回为true console.log(/[abc]/.test('andy')) // true console.log(/[abc]/.test('baby'))// true console.log(/[abc]/.test('cry')) // true console.log(/[abc]/.test('die')) // false console.log(/*[abc]$/.test('ab')) // false console.log(/*[abc]{2}$/.test('ab')) //true
[] 里面加上-连字符
使用连字符-表示一个范围 console.log(/^[a-z]$/.test('c')) // true
比如:
[a-z] 表示a到z26个英文字母都可以
[a-zA-Z]表示大小写都可以
[0-9] 表示0~9 的数字都可以
[] 里面加上^取反符号 比如: [^a-z]
匹配除了小写字母以外的字符
注意要写到中括号里面
点.匹配除换行符之外的任何单个字符
作用域
作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问。
局部作用域
局部作用域分为函数作用域和块作用域。
函数作用域
在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
function getSum() {const num = 10}//函数内部是函数作用域属于局部变量 console.log(num) // 此处报错函数外部不能使用局部作用域变量
总结:
-
函数内部声明的变量,在函数外部无法被访问
-
函数的参数也是函数内部的局部变量
-
不同函数内部声明的变量无法互相访问
-
函数执行完毕后,函数内部的变量实际被清空了
块作用域
在Javascript 中使用{}包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。
for (let t = 1; t <= 6; t++) { // t只能在该代码块中被访问 console.log(t) // 正常 } // 超出了t的作用域 console.log(t) // 报错
-
let 声明的变量会产生块作用域,var不会产生块作用域(声明的即为全局变量)
-
const 声明的常量也会产生块作用域
-
不同代码块之间的变量无法互相访问
-
推荐使用 let 或const
全局作用域
<script>
标签 和 .js 文件的【最外层]就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。全局作用域中声明的变量,任何其它作用域都可以被访问。
//全局作用域下声明了 num变量 const num =10 function fn() { // 函数内部可以使用全局作用域的变量 console.log(num) }
注意:
-
为 window 对象动态添加的属性默认也是全局的,不推荐!
-
函数中未使用任何关键字声明的变量为全局变量,不推荐!!!
-
尽可能少的声明全局变量,防止全局变量被污染
作用域链
作用域链本质上是底层的变量查找机制。
在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域。
总结:
-
嵌套关系的作用域串联起来形成了作用域链
-
相同作用域链中按着从小到大的规则查找变量
-
子作用域能够访问父作用域,父级作用域无法访问子级作用域
垃圾回收机制
垃圾回收机制(Garbage Collection)简称GC,JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收
内存的生命周期
-
内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存。
-
内存使用:即读写内存,也就是使用变量、函数等。
-
内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存。
说明:
全局变量一般不会回收(关闭页面回收)。
一般情况下局部变量的值,不用了,会被自动回收掉。
内存泄漏:程序中分配的内存由于某种原因程序未释放或无法释放叫做内存泄漏
算法说明
堆栈空间分配区别: 1.栈(操作系统):由操作系统自动分配释放函数的参数值、局部变量等,基本数据类型放到栈里面。 2.堆(操作系统):一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型放到堆里面。
引用计数法
IE采用的引用计数算法,定义“内存不再使用”,就是看一个对象是否有指向它的引用,没有引用了就回收对象算法:
-
跟踪记录被引用的次数
-
如果被引用了一次,那么就记录次数1,多次引用会累加 ++
-
如果减少一个引用就减1--
-
如果引用次数是0,则释放内存
它存在一个致命的问题:嵌套引用(循环引用) 如果两个对象相互引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄露。
function fn( ){ let o1={} let o2={} o1.a=o2 o2.a=o1 return '引用计数无法回收' } fn()
因为他们的引用次数永远不会是0。这样的相互引用如果说很大量的存在就会导致大量的内存泄露
标记清除法
现代的浏览器已经不再使用引用计数算法了。 现代浏览器通用的大多是基于标记清除算法的某些改进算法,总体思想都是一致的。
核心:
-
标记清除算法将“不再使用的对象”定义为“无法达到的对象”。
-
就是从根部(在JS中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的。
-
那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收。
闭包
概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域。
简单理解:闭包=内层函数+外层函数的变量
闭包作用:
-
封闭数据,实现数据私有,外部也可以访问函数内部的变量
-
闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来
闭包可能引起的问题:内存泄漏
函数参数
动态参数
arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参。
//求和函数,计算所有参数的和。 function sum() { // console.log(arguments) lets =e for(let i = 0; i < arguments.length; i++) { s += arguments[i] console.log(s) } sum(1,2,4)
但箭头函数没有arguments所以无法使用arguments但可以使用剩余参数。
总结:
-
arguments是一个伪数组,只存在于函数中。
-
arguments 的作用是动态获取函数的实参。
-
可以通过for循环依次得到传递过来的实参。
剩余参数
剩余参数允许我们将一个不定数量的参数表示为一个数组
function getSum(...other) { console.log(other) //得到[1,2,3] } getSum(1,2,3)
-
.... 是语法符号,置于最末函数形参之前,用于获取多余的实参
-
借助 ... 获取的剩余实参,是个真数组
function config(baseURL,...other) { console.log(baseURL) // 得到'http://baidu.com' console.log(other) //得到['get','json'] } //调用函数 config('http://baidu.com','get', 'json');
开发中,还是提倡多使用剩余参数。
展开运算符
展开运算符(...),将一个数组进行展开
const arr = [1,5,3,8,2] console.log(...arr) // 1 5 3 8 2
不会修改原数组
const arr1 = [1, 2,3] // 展开运算符 可以展开数组 // console.log(Math.max(1, 2, 3)) // ...arr1 === 1,2,3 //1 求数组最大值 console.log(Math.max(...arr1)) // 2.合并数组 const arr2 = [3, 4,5] const arr = [...arr1,...arr2]