目录
DOM和BOM
DOM(文档对象模型):操作网页内容,例如某个节点。
BOM(浏览器对象模型):操作浏览器内容,例如操作路由。
获取和操作DOM内容
DOM是什么
DOM(文档对象模型):操作网页内容,例如某个节点。
DOM树和DOM对象
DOM树是什么?
将html文档以树状结构直观的表现出来,称之为文档树或DOM树。
网页中最大的对象是什么?
document
在html中<div>叫标签,在js中叫什么?
DOM对象
获取DOM元素
获取单个DOM元素
document.querySelector('css选择器')
const div = document.querySelector('div')
注意事项:
1.选择匹配的第一个元素
2.返回值:CSS选择器匹配的第一个元素,一个 HTMLElement对象。如果没有匹配到返回null
获取一组DOM元素
document.querySelectorAll('css选择器')
const div = document.querySelectorAll('div')
注意事项和上面一致(只不过他得到的是一个伪数组,获取一个元素也是伪数组的形式)
总结:
querySelectorAll()(伪数组,哪怕只获取一个,需要遍历得到每一个元素 )
querySelector()(获取第一个元素)
小括号里面的参数注意事项?
1.里面写css选择器
2.必须是字符串,也就是必须加引号
修改获取元素内容
原理:和对象修改一样
const obj = { name: '张三', age:17 } console.log(obj.name) //读取对象的属性 obj.age = 18//更改对象的属性
语法:元素.innerHtml 和 元素.innerText
两者的区别:
元素.innerHTML 能识别文本,能够解析标签
元素.innerText 只识别文本,不能解析标签
const box = document.querySelector('.box'); // 修改文字内容 对象.innerText 不解析标签 box.innerText = '<b>我是div</b>'; ----><b>我是div</b> // innerHtml 解析标签 box.innerHTML = '<b>我是div呀吼</b>'; ---->文字加粗
通过style修改样式属性
语法:对象.style.样式属性 = '值'
一次只能修改一个样式 代码量很多
注意事项:
1.如果属性有-连接符,需要转换为小驼峰命名法(直接看打印结果也能的出来,因为-这个会被翻译成减法)
2.赋值的时候,需要的时候不要忘记加css单位
const box = document.querySelector('.box') //2. 修改样式属性 对象.style.样式属性 = '值' 跟单位!!! box.style.width = '300px' // 多组单词的采取 小驼峰命名法 box.style.backgroundColor = 'hotpink' box.style.border = '2px solid blue' box.style.borderTop = '2px solid red'
通过className类名修改样式
语法:对象.className='类名'
可以同时修改多个样式,但会覆盖以前的类名。
const div = document.querySelector('div'); // 2.添加类名 class 是个关键字 所以用className div.className = 'box' //box是类名
可以多个类名,空格隔开。
通过classList修改样式
语法:
对象.classList.add('类名') ---- 追加一个类名
对象.classList.remove('类名') ---- 删除一个类名
对象.classList.toggle('类名') ---- 切换一个类名 有就删除,没有就追加
// 1. 获取元素 const box = document.querySelector('.box') console.dir( box) // 2. 修改样式 // 2.1 追加类 add() 类名不加点,并且是字符串 // box.classList.add('active') // 2.2 删除类 remove() 类名不加点,并且是字符串 // box.classList.remove('box') // 2.3 切换类 toggle() 有还是没有啊, 有就删掉,没有就加上 box.classList.toggle('active')
三种操作样式的方法总结
1.style,加的是行内样式,优先级较高(如果改的样式少可以用这个)
2.className会影响前面的样式。
3.classList(最新的方法,可以不用影响别的样式)
对象.classList.add('类名')//追加一个类名
对象.classList.remove('类名')//删除一个类名
对象.classList.toggle('类名')//切换一个类名
获取设置表单的值
语法:
对象.value ----- 表单里用innerHtml无效
<input type="text" value="用户名"> <script> // 1 获取元素 const uname = document.querySelector('input') console.dir(uname) // 2. 获取值 获取表单里面的值 用的 表单.value console.log(uname.value) // 用户名 console.log(uname.innerHTML) // innertHTML 得不到表单的内容 // 3. 设置表单的值 uname.value = '请输入用户名' uname.type = 'password' //把文本框改为密码框 </script>
修改表单选中和禁用
checked ---- 选中吗? ture为选中 false不选中
disabled ---- 禁用吗?true为禁用 false不禁用
<input type="checkbox" name="" id=""> <button>点击</button> // 1. 获取 const ipt = document.querySelector('input') // console.log(ipt.checked) // 默认false 不选中 只接受布尔值 ipt.checked = true // 1.获取 const button = document.querySelector('button') // console.log(button.disabled) // 默认false 不禁用 button.disabled = true // 禁用按钮
H5自定义属性-data
html5中推出data-自定义属性(data-开头都是自定义属性)
在DOM对象上一律以dataset对象方式获取
<body> <div data-id="1" data-uname="张三">1</div> <div data-id="2">2</div> <div data-id="3">3</div> <div data-id="4">4</div> <div data-id="5">5</div> <script> const one = document.querySelector('div') console.log(one.dataset.id) // 1 console.log(one.dataset.spm) // 张三 </script> </body>
DOM事件基础
语法:元素对象.addEvenListener('事件类型',要执行的函数)
事件监听三要素
事件源:哪个dom元素被事件触发了,要获取dom元素。
事件类型:用什么方式触发,鼠标单击 click、鼠标经过 mouseenter、鼠标离开 mouseleave
事件调用的函数:要做什么事情
------注意事项:1.事件注册后不会立即触发,而是等待用户操作了才去触发。
2.事件类型,必须加 ' '。
3.要执行的函数每次事件类型触发了都会执行一次。
<button>点击</button> const btn = document.querySelector('button') btn.addEventListener('click', function () { alert('你完成了事件监听') })
事件类型
鼠标事件:
1.click 鼠标点击
2.mouseenter 鼠标经过
3.mouseleave 鼠标离开
焦点事件:
1.focus 获得焦点
2.blur 失去焦点
键盘事件:
1.Keydown 键盘按下的事件
2.Keyup 键盘抬起的事件
文本事件:
1.input 用户输入事件
只能通过value来获取值
事件对象和环境对象
事件对象
啥是事件对象???
想到对象就是key-value组成,属性名和属性值组成;比如键盘按下,会记录你按下了那个键,就是事件对象记录的;比如在页面点击一下,就知道是什么为止点击的,也是事件对象记录的。
语法:
元素.addEvenListener('click',function(e){}) e就是事件对象
事件对象常见的属性 --- 事件对象.属性名
type:获取当前的事件类型(看是点击事件还是键盘事件......)
target:获取触发事件的元素 -----它里面有个tagName属性可以找出哪个元素触发了指定的事件。
clientX/clientY:获取光标相当于浏览器可见左上角的位置
key:用户按下的键盘键的值
环境对象this
什么是环境对象this?
现在暂时理解成就是 谁调用 this就是谁
回调函数
代码执行不会立即执行的函数,而是等待事件触发才会执行。
注意事项:把函数当做另外一个函数的参数传递,这个函数就是回调函数。
匿名函数做为回调函数比较常见。
事件流和事件委托
事件流
- addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
- 若传入false代表冒泡阶段触发,默认就是false
- 若是用 L0 事件监听,则只有冒泡阶段,没有捕获
事件流---捕获阶段
const fa = document.querySelector('.father') const son = document.querySelector('.son') document.addEventListener('click', function () { alert('我是爷爷') },true) fa.addEventListener('click', function () { alert('我是爸爸') },true) son.addEventListener('click', function (e) { alert('我是儿子') },true)
捕获阶段会依次向下寻找 ,父—>子。上述代码中如果触发son的点击事件,会先弹出"我是爷爷"-->"我是爸爸" -->"我是儿子"
事件流---冒泡阶段
const fa = document.querySelector('.father') const son = document.querySelector('.son') document.addEventListener('click', function () { alert('我是爷爷') }) fa.addEventListener('click', function () { alert('我是爸爸') }) son.addEventListener('click', function (e) { alert('我是儿子') })
冒泡阶段:
当一个元素触发事件后,会依次向上调用所有父级元素的 同名事件(同类型,click只会是click,mouseenter只会是mouseenter)
上述代码中如果触发son的点击事件,会先弹出"我是儿子" --->"我是爸爸" --->"我是爷爷"
阻止事件冒泡
语法:事件对象.stopPropagation()
// 事件冒泡 从子到父 document.addEventListener('click', function () { alert('爷爷') }) father.addEventListener('click', function () { alert('爸爸') }) son.addEventListener('click', function (e) { alert('儿子') // 阻止冒泡 不在往上冒泡 e.stopPropagation(); })
上述代码中,只会弹出"儿子",不会在向上调用了。
阻止默认行为---阻止 链接的跳转,表单域跳转
语法:事件对象.preventDefault()
const a = document.querySelector('a'); a.addEventListener('click',function(e){ e.preventDefault() //阻止默认行为 例 a链接跳转 表单的提交 }) const btn = document.querySelector('input'); btn.addEventListener('click',function(e){ e.preventDefault() })
事件解绑
const btn = document.querySelector('button'); /* btn.onclick = function(){ alert('点击了'); // L0事件移除解绑 btn.onclick = null; } */ // L2的解绑方式 function fn(){ alert('点击了'); } btn.addEventListener('click',fn) // L2事件移除解绑 btn.removeEventListener('click',fn);
注意:匿名函数无法被解绑
mouseover和 mouseenter区别
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果(推荐)
事件委托
好处:减少注册次数,提高程序的性能。给父级元素设置事件,儿子元素会因为事件冒泡也会拥有父级元素的事件。
原理:利用事件冒泡的特点
其他事件和元素尺寸及位置
页面加载事件load
可以帮助我们解决js代码只能写在body下面的问题。
语法:1)window.addEventListener('load', function () {})//监听页面所有资源加载完毕,执行function里面的代码
2)window.addEventListener('DOMContentLoaded', function () {})//监听 HTML 文档被完全加载和解析完成之后,执行function里面的代码
DOMContentLoaded更加快一点,给document加,无需等待样式表、图像完全加载。
页面滚动事件
很多网页需要检测用户把页面滚动到某个区域后做一些处理,比如固定导航栏,比如返回顶部。
语法:window.addEventListener('scroll',function() {})
const div = document.querySelector('div') div.addEventListener('scroll', function () { // scrollTop 被卷去的头部 console.log(div.scrollTop) })
获取页面滚动被卷去的头部 ---scrollTop
获取body:document.body
获取html:document.documentElement
document.body //获取body document.body.scrollTop //获取body的滚动距离 document.documentElement //获取html document.documentElement.scrollTop //获取html的滚动距离
注意:scrollTop是可读写的,必须写到里面,滚动事件触发的时候每次重新拿这个值,得到的是 数字型 不带单位。
document.documentElement.scrollTop = 800 //这个值是可读写的 window.addEventListener('scroll', function () { const n = document.documentElement.scrollTop // 必须写到里面 // 得到是什么数据 数字型 不带单位 // console.log(n) })
clientWidth获取元素位置
语法:window.addEventListener('resize', function () {})
resize 浏览器窗口大小发生变化的时候触发的事件
clientWidth = padding+width
const div = document.querySelector('div') console.log(div.clientWidth)//这个是属性
offsetWidth获取元素位置
offsetWidth = padding+width+border
const div = document.querySelector('div') console.log(div.offsetWidth)//这个是属性
offsetLeft和offsetTop语法:
/获取元素距离自己定位父级元素的左、上距离 //offsetLeft和offsetTop 注意是只读属性 const div = document.querySelector('div') const p = document.querySelector('p') // console.log(div.offsetLeft) // 检测盒子的位置 最近一级带有定位的祖先元素 console.log(p.offsetLeft)//这个是属性
注意:获取元素距离自己定位父级元素的左、上距离;他们都是只读属性。
日期对象和DOM节点
实例化日期对象
new新的,就要创建一个新的对象{ }
语法:const date = new Date() --->得到当前时间
const date1 = new Date('2022-5-1 08:30:00') --->得到指定时间
常见的日期对象方法
// 获得日期对象 const date = new Date() // 使用里面的方法 console.log(date.getFullYear()) console.log(date.getMonth() + 1) // 月份要 + 1 console.log(date.getDate()) console.log(date.getDay()) // 星期几
格式化日期格式 --- YYYY-MM-DD HH:mm
调用日期对象方法进行转换
记得数字要补0
字符串拼接后,通过 innerHTML 给 标签
const div = document.querySelector('div') function getMyDate() { const date = new Date() let h = date.getHours() let m = date.getMinutes() let s = date.getSeconds() h = h < 10 ? '0' + h : h m = m < 10 ? '0' + m : m s = s < 10 ? '0' + s : s return `今天是: ${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}号 ${h}:${m}:${s}` } div.innerHTML = getMyDate() setInterval(function () { div.innerHTML = getMyDate() }, 1000)
固定时间样式的内置写法 只能YYYY/MM/DD
日期对象.toLocaleString()
const div = document.querySelector('div') // 得到日期对象 const date = new Date() div.innerHTML = date.toLocaleString() // '2022/9/11 14:38:27' setInterval(function () { const date = new Date() div.innerHTML = date.toLocaleString() }, 1000) //div.innerHTML = date.toLocaleString() // '2022/9/11 14:38:17' //div.innerHTML = date.toLocaleDateString() // '2022/9/11' //div.innerHTML = date.toLocaleTimeString() // '14:38:07'
时间戳的作用
定义:是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式。
原因:因为时间不好加减计算,利用时间戳可以弥补
获得时间戳的三种方式
// 1. getTime() //方式一 const date = new Date() console.log(date.getTime()) // 2. +new Date()//方式二 console.log(+new Date()) //获得指定日期console.log(+new Date('2022-4-1 18:30:00')) // 3. Date.now()//方式三 //只能得到当前的时间戳 console.log(Date.now());
总结:喜欢用那个用那个,注意Date.now() 只能得到当前的时间戳
DOM节点
DOM节点:DOM树里每一个内容都是节点
节点类型:
元素节点:所有的标签 比如body、div、html是根节点
属性节点:所有的属性 比如 href src
文本节点:所有的文本
查找父节点
语法:元素.parentNode 找亲爹 --- 元素.parentNode.parentNode 找亲爷爷
const baby = document.querySelector('.baby') console.log(baby) // 返回dom对象 console.log(baby.parentNode) // 返回dom对象 亲爹 console.log(baby.parentNode.parentNode) // 返回dom对象 亲爷爷
子节点和兄弟节点
子节点查找语法:
元素.childNodes 获得所有子节点、包括文本节点(空格、换行)、注释节点等
元素.children 仅获得所有元素节点,返回的是一个为数组 推荐
//方式一:childNodes (了解即可) //获得所有子节点、包括文本节点(空格、换行)、注释节点等 const ul = document.querySelector('ul') // ul console.log(ul.childNodes) //这玩意不用打印看下 //方式二:children 属性 (重点) //仅获得所有元素节点 //返回的还是一个伪数组 const ul = document.querySelector('ul') // ul console.log(ul.children)
兄弟节点查找语法
元素.previousElementSibling 上一个兄弟
元素.nextElementSibling 下一个兄弟
const li2 = document.querySelector('ul li:nth-child(2)') console.log(li2.previousElementSibling) // 上一个兄弟 console.log(li2.nextElementSibling) // 下一个兄弟
增加节点
步骤:创建节点 - 插入节点
增加节点语法:document.createElement('标签名') --- 创建节点
父元素.appendChild('标签名') --- 追加节点 作为最后一个元素
// 1. 创建节点 const div = document.createElement('div') // console.log(div) //2. 追加节点 作为最后一个子元素 document.body.appendChild(div)
插入语法:
父元素.appendChild('要插入的元素') --- 插入的父元素的最后
父元素.insertBefore('要插入的元素', '放到哪个元素的前面') --- 插入到父元素中某个子元素的前面const ul = document.querySelector('ul') // 创建节点 const li = document.createElement('li') li.innerHTML = '我是li' //插入到父元素后面 // ul.appendChild(li) // insertBefore(插入的元素, 放到哪个元素的前面) ul.insertBefore(li, ul.children[0])
删除节点
语法:父元素.remove(子元素)
const ul = document.querySelector('ul') // 删除节点 父元素.removeChlid(子元素) ul.removeChild(ul.children[0])
总结:查找父节点、查找子节点、查找兄弟节点。全都是属性,不要加括号。
节点增加的语法:
document.createElement('标签名') --- 创建节点
父元素.appendChild('要插入的元素') --- 插入的父元素的最后
父元素.insertBefore('要插入的元素', '放到哪个元素的前面') --- 插入到父元素中某个子元素的前面克隆节点
语法:元素.cloneNode(true)
//为true,则代表克隆时会包含后代节点一起克隆 //若为false,则代表克隆时不包含后代节点 默认为false //实现 const ul = document.querySelector('ul') // 1 克隆节点 元素.cloneNode(true) const li1 = ul.children[0].cloneNode(true) console.log(li1) // 2. 追加 // ul.appendChild(ul.children[0].cloneNode(true)) ul.appendChild(li1)
移动端事件以及插件
移动端事件
tochstart:手指触摸到一个dom元素时触发
touchmove:手指在一个dom元素上滑动时触发
touchend:手指从一个dom元素上移开时触发
const div = document.querySelector('div') // 1. 触摸 div.addEventListener('touchstart', function () { console.log('开始摸我了') }) // 2. 离开 div.addEventListener('touchend', function () { console.log('离开了') }) // 3. 移动 div.addEventListener('touchmove', function () { console.log('一直摸,移动') })
回流和重绘
回流/重排:
当页面中部分或者全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或者全部文档的过程称为回流/重排。
重绘:
因为节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局(比如:color、background-color、outline等),称为重绘
重绘不会引起回流/重排,但是回流/重排一定会引起重绘 ---- 就像一个盒子的背景颜色改变了,但盒子大小并没有改变也不影响布局结构。但是盒子的大小如果发生变化,背景颜色的大小肯定会发生改变。
window对象
BOM简介
浏览器对象模型
定时器-延迟函数
语法:setTimeout(回调函数,等待的毫秒数)
//setTimeout 仅仅只执行一次 setTimeout(回调函数, 等待的毫秒数) setTimeout(function () {}, 2000) //清除定时器 let timer = setTimeout(回调函数, 等待的毫秒数) clearInterval(timer)
location对象
search:通过location.search可以拿到 ?后面的值
hash:通过location.hash可以拿到 # 后面的值
reload:通过location.reload()可以刷新页面
reload(true):强制刷新,不加true就是普通刷新
<form action=""> <input type="text" name="uname" id=""> <input type="password" name="pwd" id=""> <button>提交</button> </form> <a href="#my">我的</a> <a href="#load">本地</a> <a href="#download">下载</a> <button class="btn">刷新</button> <script> // 获取地址栏信息 console.log(location.href); // 修改地址栏信息 // location.href = 'https://www.baidu.com' // 获取地址栏中 ? 后面的内容 console.log(location.search); // ?uname=123&pwd=321 // 获取地址栏 # 后面的内容 console.log(location.hash); // #my #load #download const btn = document.querySelector('.btn'); btn.addEventListener('click',function(){ // 普通刷新 // location.reload(); // 强制刷新 location.reload(true); }) </script>
navigator对象
定义:navigator对象下记录了浏览器自身的相关信息
userAgent检测浏览器的版本及平台
// 检测 userAgent(浏览器信息) !(function () { const userAgent = navigator.userAgent // 验证是否为Android或iPhone const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/) const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/) // 如果是Android或iPhone,则跳转至移动站点 if (android || iphone) { location.href = 'http://m.itcast.cn' } })()
history对象
定义:history 主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等。
常见的方法:
back():可以后退功能
forward():前进功能
go(参数):1为前进 -1为后退
const back = document.querySelector('button:first-child') const forward = back.nextElementSibling back.addEventListener('click', function () { // 后退一步 // history.back() history.go(-1) }) forward.addEventListener('click', function () { // 前进一步 // history.forward() history.go(1) })
本地存储
本地存储的介绍
本地存储就是数据存储在用户浏览器中
特点:
容量较大,sessionStorage和localStorage约5M左右。
设置、读取方便、甚至页面刷新不丢失数据
本地存储localStorage使用
语法:
localStorage.setItem('键','值') --- 存储语法
localStorage.getItem('键') --- 获取语法
localStorage.removeItem('键') --- 删除本地存储
<script> // 存储 本地存储只能存储字符串数据类型 localStorage.setItem('uname','zs'); localStorage.setItem('age',18); // 改 如果原来有这个键,则是改,如果没有这个键是增 localStorage.setItem('uname', 'ls') // 得到 console.log(localStorage.getItem('uname')); console.log(localStorage.getItem('age')); // 删除 localStorage.removeItem('age'); </script>
注意事项:
本地存储只能存储字符串数据类型
sessionStorage跟localStorage的语法是一样的,不同的是localStorage关闭浏览器窗口数据仍然存在,sessionStorage关闭浏览器窗口之后数据也就消失了。
在同一个窗口(页面)下数据可以共享
本地存储存储复杂数据类型
本地存储存储复杂数据类型不能直接存,需要转化为字符串。利用JSON对象
JSON字符串存储
1.属性和值有引号,而且统一都是双引号
2.不能写注释
字符串和对象相互转化的方法
转换为JSON字符串:JSON.stringify(对象)
JSON字符串转换为对象:JSON.parse(字符串)
const obj = { uname: 'zs', age: 18, gender: '女' } // 存储 复杂数据类型 无法直接使用 localStorage.setItem('obj', obj) // 取 console.log(localStorage.getItem('obj'))//[object object] // 1.复杂数据类型存储必须转换为json字符串 localStorage.setItem('obj', JSON.stringify(obj)) // 2. 把JSON字符串转换为 对象 const str = localStorage.getItem('obj') // {"uname":"zs","age":18,"gender":"女"} console.log(JSON.parse(str))
JS执行机制
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
同步和异步
同步:同步任务都在主线程上执行,形成一个执行栈。
异步:JS的异步是通过回调函数实现的。常见的有
1.普通事件,如click、resize等
2.资源加载,如load,error等
3.定时器,包括 setInterval、setTimeout 等
事件循环event loop
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)。--- 代表一个过程,不是一个事物。
数组map方法
map方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。
作用:遍历数组;处理数据;返回一个新数组。
const arr = ['red', 'blue', 'green'] // map 方法也是遍历 处理数据 可以返回一个数组 const newArr = arr.map(function (item, i) { // console.log(item) // 数组元素 // console.log(i) // 下标 return item + '老师' }) console.log(newArr)// ['red老师', 'blue老师', 'green老师']
数组join方法
join方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组中只有一个项目,那么将返回该项目而不使用分隔符
const arr = ['red', 'blue', 'green'] // 把数组元素转换为字符串 console.log(arr.join('*')) // red*blue*green
正则表达式
正则表达式是什么以及作用
白话定义:校验和匹配字符
官方定义:是用于匹配字符串中字符组合的模式
作用:
1.表单验证(匹配)
2.过滤敏感词(替换)
3.字符串中提取我们想要的部分(提取)
正则表达式的使用
语法:
const 变量名 = / 表达式 /
查找语法:
test() 方法 用来查看正则表达式与指定的字符串是否匹配,返回 true 或 false
// 语法
reg.test(被监测的字符串)
// 举例
const str = '我们在学习前端,希望学习前端能高薪毕业' const reg = /前端/ reg.test(str) //true
test和exec的区别
exec()方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或null。
//语法 reg.test(被监测的字符串) //举例 const str = '我们在学习前端,希望学习前端能高薪毕业' const reg = /前端/ reg.exec(str)
元字符
定义:是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
元字符之边界符
^:表示匹配行首的文本(以谁开始)
$:表示匹配行尾的文本(以谁结束)
注意:如果 ^ 和 $ 在一起,表示必须是精确匹配。
元字符之量词符号写法
元字符之量词大括号写法