JavaScript入门5

正则表达式

正则表达式是一种用来描述字符串匹配模式的表达式。它由普通字符(例如字母、数字、符号)和特殊字符(元字符)组成,通过这些字符的组合可以描述字符串的特定模式。

正则表达式可以用于多种文本处理任务,包括搜索、替换、验证和提取字符串。

语法

定义规则:

const 变量名 = /表达式/

 是否匹配:

test()用于检测正则表达式与指定字符串是否匹配的方法

regexp.test(str)
  • regexp 是一个正则表达式对象,用于匹配字符串。
  • str 是要与正则表达式进行匹配的字符串。

test() 方法返回一个布尔值:

  • 如果字符串 str 符合正则表达式 regexp 的规则,则返回 true
  • 如果字符串 str 不符合正则表达式 regexp 的规则,则返回 false
var str = "Hello, world!";
var regexp = /Hello/;
var result = regexp.test(str);

console.log(result); // 输出 true

exec()用于在字符串中执行一个搜索匹配的方法,它返回一个数组(或者 null,如果没有找到匹配)。

regexp.exec(str)
  • regexp 是一个正则表达式对象,用于在字符串 str 中执行搜索。
  • str 是要在其中执行搜索的字符串。

exec() 方法返回一个数组:

  • 如果找到了匹配,返回一个数组,其中第一个元素是匹配的子字符串,接下来的元素是与捕获组匹配的字符串(如果有的话)。
  • 如果没有找到匹配,返回 null
var str = "Hello, world!";
var regexp = /Hello/;
var result = regexp.exec(str);

console.log(result); // 输出 ["Hello"], index: 0, input: "Hello, world!"

 量词

在正则表达式中,量词用于指定模式重复出现的次数。它们允许我们匹配特定数量的字符或模式。

以下是一些常见的正则表达式量词:

  1. *:匹配前面的模式零次或多次。

    • 例如,a* 可以匹配空字符串、"a"、"aa"、"aaa" 等。
  2. +:匹配前面的模式一次或多次。

    • 例如,a+ 可以匹配 "a"、"aa"、"aaa" 等,但不能匹配空字符串。
  3. ?:匹配前面的模式零次或一次。

    • 例如,a? 可以匹配空字符串或 "a"。
  4. {n}:匹配前面的模式恰好出现 n 次。

    • 例如,a{3} 只能匹配 "aaa"。
  5. {n,}:匹配前面的模式至少出现 n 次。

    • 例如,a{2,} 可以匹配 "aa"、"aaa"、"aaaa" 等。
  6. {n,m}:匹配前面的模式至少出现 n 次,但不超过 m 次。

    • 例如,a{2,4} 可以匹配 "aa"、"aaa"、"aaaa",但不能匹配 "a" 或 "aaaaa"。

 元字符

元字符是具有特殊含义的字符,用于匹配文本的模式。

.:匹配除换行符以外的任意字符。

^:匹配字符串的开头。

$:匹配字符串的结尾。

*:匹配前面的元素零次或多次。

+:匹配前面的元素一次或多次。

?:匹配前面的元素零次或一次。

\:转义字符,用于匹配特殊字符本身,如\.匹配句点。

[]:字符集,匹配括号内的任意一个字符。

  • [abc]:匹配字符 a、b 或 c。
  • [a-z]:匹配任意小写字母。
  • [^0-9]:匹配任意非数字字符。

|:逻辑或,用于匹配两者之一。

  • cat|dog:匹配 "cat" 或 "dog"。

():分组,将多个项组合为一个单元。

  • (ab)+:匹配 "ab"、"abab"、"ababab" 等。

修饰符

i:不区分大小写匹配。

  • 例如,/hello/i 可以匹配 "hello"、"Hello"、"HELLO" 等。

g:全局匹配,即匹配所有符合条件的字符串,而不仅仅是第一个。

  • 例如,/hello/g 可以匹配 "hello"、"hello, world! hello" 中的所有 "hello"。

m:多行匹配,使 ^$ 分别匹配一行的开头和结尾,而不仅仅是整个输入字符串的开头和结尾。

  • 例如,/^hello/m 可以匹配以 "hello" 开头的每一行。

练习:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .error{
      color: red;
    }

    .right{
      color: green;
    }
  </style>
</head>
<body>
  <input type="text" name="username">
  <span></span>
  <script>
    const input = document.querySelector('[name=username]')
    input.addEventListener('change',phone)
    function phone(){
    const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\9[0-35-9])\d{8}$/
    input.nextElementSibling.innerHTML = '';
    input.nextElementSibling.classList.remove('error', 'right');

    if(reg.test(input.value)){
        input.nextElementSibling.innerHTML = '输入正确';
        input.nextElementSibling.classList.add('right');
    }else{
        input.nextElementSibling.innerHTML = '请输入正确的手机号码';
        input.nextElementSibling.classList.add('error');
    }
}

  </script>
</body>
</html>

作用域 

局部作用域

局部作用域分为函数作用域和块作用域。

函数作用域:

函数作用域指的是在函数内部声明的变量(包括函数参数),其作用域范围仅限于该函数内部,无法从函数外部访问。这意味着函数内部的变量在函数执行完毕后就会被销毁,不再存在于内存中。

函数作用域具有以下特点:

  1. 变量提升(Variable Hoisting):在 JavaScript 中,函数内部声明的变量会被提升到函数作用域的顶部。这意味着你可以在函数内部任何位置使用变量,即使在变量声明之前,因为变量声明会被提升到作用域顶部。

  2. 作用域嵌套(Nested Scopes):JavaScript 允许在一个函数内部定义另一个函数,形成嵌套的作用域关系。内部函数可以访问外部函数的变量,但外部函数不能访问内部函数的变量。

  3. 闭包(Closure):由于函数作用域的特性,函数内部的变量可以被函数外部的其他函数或代码访问,

    形成了闭包。闭包在 JavaScript 中经常用于创建私有变量和实现模块化等功能。

    function outerFunction() {
      var outerVariable = 'I am in outer function';
    
      function innerFunction() {
        var innerVariable = 'I am in inner function';
    
        console.log(outerVariable); // 可以访问外部函数的变量
        console.log(innerVariable); // 可以访问内部函数的变量
      }
    
      innerFunction();
    }
    
    outerFunction();
    

块作用域

块作用域指的是变量的作用域范围限定在块级代码块(由一对花括号 {} 包裹)内部,而不再仅限于函数内部。在块作用域中声明的变量只在该代码块内部有效,并且在代码块外部无法访问。

使用块作用域有助于减少变量的污染和提供更好的代码封装性。通常,使用 letconst 关键字来声明块级作用域的变量。

function example() {
  if (true) {
    var functionScoped = 'I am in function scope';
    let blockScoped = 'I am in block scope';
    const alsoBlockScoped = 'I am also in block scope';
  }

  console.log(functionScoped); // 可以在块外部访问,因为是函数作用域
  console.log(blockScoped); // 报错,无法在块外部访问,因为是块级作用域
  console.log(alsoBlockScoped); // 报错,无法在块外部访问,因为是块级作用域
}

example();

全局作用域

全局作用域是指在整个 JavaScript 程序中都可以访问的作用域范围。在全局作用域中声明的变量和函数可以被代码中的任何部分访问,其生命周期在整个程序执行期间都有效。

在浏览器环境中,全局作用域通常指的是 window 对象,即全局对象。所有在全局作用域下声明的变量和函数实际上都成为了 window 对象的属性,可以通过 window.variableNamewindow.functionName() 的方式进行访问。

var globalVariable = 'I am in global scope';

function globalFunction() {
  console.log('I am a global function');
}

console.log(globalVariable); // 可以直接访问全局变量
globalFunction(); // 可以直接调用全局函数

作用域链 

作用域链(Scope Chain)是指在 JavaScript 中变量和函数的查找顺序。当代码在一个函数内部访问一个变量时,JavaScript 引擎会按照作用域链从内到外依次查找变量,直到找到为止。作用域链的形成是由代码中函数的嵌套结构所决定的。

在 JavaScript 中,每个函数都有自己的作用域,而作用域链是由这些嵌套的函数作用域所连接而成的。当在一个函数内部引用一个变量时,JavaScript 引擎首先查找当前函数的作用域内是否有该变量,如果没有,它会沿着作用域链向上查找,直到找到为止。如果最终在全局作用域中也找不到该变量,那么会抛出 ReferenceError。

var a = 10;

function outerFunction() {
  var b = 20;
  
  function innerFunction() {
    var c = 30;
    console.log(a); // 在 innerFunction 中查找变量 a,沿着作用域链找到了全局变量 a
    console.log(b); // 在 innerFunction 中查找变量 b,直接在 outerFunction 中找到了变量 b
    console.log(c); // 直接在 innerFunction 中找到变量 c
  }
  
  innerFunction();
}

outerFunction();

垃圾回收装置

垃圾回收(Garbage Collection)是一种自动内存管理机制,用于在程序运行时识别和回收不再被程序使用的内存资源,以避免内存泄漏和提高程序的性能。

以下是垃圾回收机制的一些关键概念和工作原理:

  1. 标记清除(Mark and Sweep):这是最常见的垃圾回收算法之一。它通过标记所有活动对象,然后清除未标记的对象来回收内存。这个过程包括标记阶段和清除阶段。

  2. 引用计数(Reference Counting):另一种常见的垃圾回收算法,它通过跟踪每个对象的引用计数来判断对象是否可回收。当引用计数为零时,表示对象不再被使用,可以被回收。

  3. 分代垃圾回收(Generational Garbage Collection):这是一种基于对象生存周期的策略,将内存中的对象分为不同的代,根据对象的存活时间进行不同频率的回收操作,提高了回收效率。

  4. 内存碎片整理(Memory Defragmentation):随着程序的运行,内存可能会产生碎片化,影响内存的分配和使用效率。一些垃圾回收算法会对内存进行整理,将存活对象集中放置,减少内存碎片。

  5. 停顿时间(Pause Time):垃圾回收会暂停程序的执行来进行内存回收操作,这可能引起程序的停顿。优秀的垃圾回收算法会尽量减少停顿时间,以提高程序的响应性能。

JS闭包

闭包(Closure)是指能够访问其词法作用域外部变量的函数。换句话说,闭包是内部函数可以访问外部函数作用域中变量的函数。在 JavaScript 中,由于函数是一等公民,函数可以作为参数传递、赋值给变量,也可以在另一个函数内部定义,从而形成闭包。

闭包通常发生在一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量。这样内部函数就形成了对外部函数作用域的闭包,即使外部函数已经执行完毕,内部函数依然可以访问和操作外部函数的变量。

变量提升

变量提升: 在 JavaScript 中,使用 var 关键字声明的变量会发生变量提升。这意味着无论变量的声明在代码中的哪个位置,都会被提升到当前作用域的顶部,但是变量的赋值不会被提升。

console.log(myVar); // 输出 undefined
var myVar = 5;

函数提升: 与变量提升类似,使用 function 关键字声明的函数也会发生函数提升。这意味着函数的声明会被提升到当前作用域的顶部,使得函数可以在声明之前被调用。

myFunc(); // 输出 "Hello"
function myFunc() {
  console.log("Hello");
}

函数参数

动态参数

arguments 是一个特殊的对象,它包含了在函数调用时传递的所有参数。它可以在函数内部使用,无需提前声明。

arguments 对象类似于数组,可以通过索引访问其中的参数值。它具有 length 属性来表示传递的参数数量。

function getSum(){
    let sum = 0
    for(let i = 0;i < arguments.length;i++{
        sum += arguments[i]
    }
    console.log(sum)
}
getSum(2,3,4)//9

剩余参数

函数剩余参数指的是通过在函数声明中使用 ... 前缀的形式,将多余的参数收集到一个数组中。这样做的好处是可以让函数接收任意数量的参数,并能够方便地在函数体内进行处理。

function sum(...numbers) {
  console.log(numbers)
}

console.log(sum(1, 2, 3, 4, 5));
console.log(sum(1, 2)); 

展开运算符

展开运算符(Spread Operator)是 ES6 引入的一种语法,使用三个点 (...) 将一个数组或类数组对象展开成独立的元素序列。

求最大值

const arr = [1, 2, 3]
console.log(Math.max(...arr))

链接数组

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];
console.log(arr2); // 输出:[1, 2, 3, 4, 5, 6]

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值