api&es6知识点汇总,持续更新中

发布时间 2023-05-23 16:08:57作者: yxxcl

Api

1. 获取dom元素

const x = document.querySelector('选择器') querySelectorAll返回的是伪数组

2. 操作元素内容

对象.innerText

对象.innerHTML 会解析标签

3. 操作元素样式属性

1. style

<script>
   const div = document.querySelector('.box')
   box.style.width = '300px'//x.style.x
   box.style.backgroundColor = 'yellow'//识别不出-,所以用小驼峰命名
   box.style.borderTop = '2px solid green'
</script>

2. 操作类名className

<script>
   const div = document.querySelector('div')
   div.className = 'box'//className会替换之前的类名,''可以用来删除,''内可以添加多个类名
</script>
<script>
//element.classList.add/remove/toggle('')(追加/删除/切换)
const box = document.querySelector('.box')
box.classList.add('active')//classList修改的类名不加点,而且字符串
box.classList.toggle('active')//有就删,没有就加上
</script>

3. 操作表单元素属性

<input type="text" value="computer">
<script>
const uname = document.querySelector('input')
</script>

name.value才能修改表单内容

uname.type = 'password'修改input类型

<input type="checkbox" value="" id="" checked>
<button disabled>click</button>
<script>
const ipt = document.querySelector('input')
const button = document.querySelector('button')
</script>

ipt.checked = false修改选择框状态

button.disabled = truebutton默认无法点击状态

4.data-set自定义属性

自定义属性:data-开头(html5),在data对象上一律以dataset对象方式获取。

标准属性:标签自带:class id title;可以使用点语法操作:disabled,checked,selected。

<div class="box1" data-id="10" data-zidingyi="自定义"></div>
<script>
const box = document.querySelector('.box1')
console.log(box.dataset);//set意为集合,所有的自定属性
</script>

见3-2法2事件委托实例

5.定时器-间歇函数

<script>
function fn(){
console.log('per 1s');
}
let n = setInterval(fn,1000)//每隔1000ms自动调用fn函数,不能写fn(),不然就是直接调用了。
console.log(n);//加上序号,即确认是页面里哪个计时器
clearInterval(n)//关闭计时器,有变量名才好关
</script>

如果不将 setInterval() 的返回值赋值给一个变量,那么就无法通过该变量来清除对应的定时器,因为 clearInterval() 需要传入 setInterval() 返回的值作为参数来清除对应的定时器。如果没有保存该返回值,则无法取消定时器。

6.事件监听

事件对象.addEventListener('事件类型',要执行的函数)

三要素:

1.事件源:哪个dom元素被触发,获取dom元素

2.事件类型:什么方式触发:click,mouseover

3:事件调用的函数:要做什么

事件类型:

鼠标事件:click,mouseover,mouseleave,mouseenter

焦点事件(表单获得光标):focus,blur(失去)

键盘事件:keydown,keyup

文本事件:input

HTMLElement.click() 方法可以用来模拟鼠标左键单击一个元素。

7.事件对象e

事件函数的回调函数绑定的第一个参数就是事件对象,console里

常见属性:

type:获取当前事件类型

clientX/Y:获得光标相对浏览器可见窗口左上角的位置

offsetX/Y:获取光标相对当前DOM元素左上角的位置

key:用户按下的键盘的键值

8.环境对象this

1. 每个函数里都有

2. 普通函数里this指向window

3. this指向函数的调用者

9.回调函数

<script>
function fn() {
console.log('这是一个回调函数');
}
setInterval(fn,1000)
const box = document.querySelector('.box')
box.addEventListener('click',function (params) {
console.log('此方程是addEventListener的回调函数');
})
</script>

10.事件流

事件流:事件完整执行过程中的流动路径

a. 捕获阶段(从父到子):document - element html - element body - element div

b. 冒泡阶段(从子到父):反过来,项目以事件冒泡为主

捕获和冒泡是事件传播的两种机制。在一个嵌套的 HTML 元素中,如果一个元素上触发了事件,这个事件会在该元素的祖先元素和后代元素中传递。

捕获是从最外层元素开始,逐级向下传递事件,直到到达目标元素。而冒泡则是从目标元素开始,逐级向上传递事件,直到到达最外层元素。在 DOM 标准事件模型中,先执行捕获阶段,然后执行目标阶段,最后执行冒泡阶段。

默认情况下,所有事件都是冒泡的,可以通过 addEventListener 的第三个参数来控制事件是在捕获阶段还是冒泡阶段处理。如果第三个参数是 true,则表示在捕获阶段处理事件;如果是 false 或者省略,则表示在冒泡阶段处理事件。

捕获和冒泡机制的应用场景比较广泛,比如可以用来处理事件委托,提高性能。当有大量子元素需要绑定事件时,可以将事件绑定到它们的父元素上,通过事件传播机制来处理事件。这样可以减少事件处理器的数量,提高性能

c. 阻止冒泡:阻止事件流动传播(捕获&冒泡),将事件限制在当前元素内: 函数名.stopPropagation()

11.事件解绑

const btn = document.querySelector('button')
function fn() {
alert('click')
}
btn.addEventListener('click',fn)
//L2事件解绑,匿名函数无法被解绑
btn.removeEventListener('click',fn)

12. 鼠标经过事件

mouseover&mouseut有冒泡效果,子元素没有事件会冒泡到父级

mouseenter&mouseleave没有冒泡效果(推荐)

13. 事件委托:委托给父元素,减少注册次数,提高程序性能

多个li需要循环让每一个注册事件,利用冒泡给父元素注册事件,会从子元素冒泡到父元素

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<p>no color</p>
</ul>
<script>
const ul = document.querySelector('ul')
ul.addEventListener('click',function (e) {
console.log(e);
console.log(e.target);//log输出源代码,点击的那个对象
console.dir(e.target);//点击的那个对象,dir输出对象内容,所有属性和方法
// e.target.style.color = 'red'//点啥都变色
if (e.target.tagName === 'LI') {
e.target.style.color = 'red'
}
})
</script>

事件对象e中有一个属性target,属性值为我们点击的(上面的为li或p),但是 e.target得到的是我们点击的那个对象,但不一定ul中所有的我们都需要让其变色,需求只点击li有效果;

所以可以通过e.target.tagName获取真正的元素,这个tagName的LI一定要大写!

14. 阻止冒泡/元素默认行为

阻止链接跳转,表单域跳转:e.preventDefault()

<form action="http://www.itcast.cn">
<input type="submit" value="login">
</form>
<script>
const form = document.querySelector('form')
form.addEventListener('click',function (e) {
e.preventDefault( )//阻止提交
})
</script>

15. 页面加载事件/元素滚动事件/页面尺寸事件

1.页面加载事件

加载外部资源(图片,外联css&js)加载完毕时触发的事件:load

不仅可以整个页面加载完毕,也可针对某个资源绑定load资源

<button>1</button
<script>
//等待页面所有资源加载完毕,就回去执行回调函数
window.addEventListener('load',function ( ) {
const btn = document.querySelector('button')
btn.addEventListener('click',function () {
alert('11')
})
})
img.addEventListener('load',function () {
//等待图片加载完毕再执行
})
//DOMContentLoaded:当初始html文件被解析加载完成,DOMContentLoaded事件被触发,无需等待样式表,图像完全加载。
//监听页面加载完毕:给domcument添加DOMContentLoaded事件。
document.addEventListener('DOMContentLoaded',function () {
})
</script>

2. 元素滚动事件(scroll)

检测用户滚动到某个区域后做一些处理:固定导航栏,返回顶部...

<script>
window.addEventListener('scroll',function () {//给window加
alert('1')
})
</script>

获取位置scrollLeft scrollTop:可读写,获取被滚动的大小

<div class="box" style="width: 100px;
height: 100px; overflow: scroll; border: 1px solid black; margin: 200px;">
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
</div>
<script>
const box = document.querySelector('.box')
box.addEventListener('scroll',function () {
console.log(box.scrollTop);//被卷上去的头部
console.log(box.scrollTop);
})
//想知道页面滚动了多少像素,获取html元素写法,document.documentElement返回对象是html元素
window.addEventListener('scroll',function () {
console.log(document.documentElement.scrollTop);
if (document.documentElement.scrollTop>=100) {
box.style.display = 'block'
}else{
box.style.display = 'none'
}
})
//可读写:document.documentElement.scrollTop=800即打开在800的位置
</script>

3.页面尺寸事件

窗口改变时触发事件(resize)

<script>
window.addEventListener('resize',function () {//窗口尺寸改变触发事件
console.log(1);
})
//检测屏幕宽度
window.addEventListener('resize',function () {
const w = document.documentElement.clientWidth
console.log(w);
})
</script>

clientWidth,clientHeight:获取元素的可见部分宽高,不含margin,边框,滚动条。。。

<div class="box" style="height: 200px;  padding: 100px; display: inline-block; border: 20px solid red;">123456789123456789123456789123456789</div>
<script>
const box = document.querySelector('.box')
console.log(box.clientWidth);
</script>

16. 元素尺寸于位置

令元素滚动到某个元素(得到元素在页面中位置)就做什么事,而非计算滚动到某距离。

offsetWidth,offsetHeigh:获取元素的自身宽高,包含元素自身设置的宽高:内容+padding+border

获取的是数值,方便计算(与client区别是offset多了一个自身边框)

注意:1.获取的是可视宽高,如果隐藏了就为0;

2.二者皆为只读属性,scroll是可读写

3.是距离自己定位父级元素的左上距离,距自己最近一级带有定位的祖先元素。

<div class="box" style=" margin: 100px; width: 200px;
height: 200px;"><p style=" width: 100px; height: 100px; margin: 50px;"></p></div>
<!-- 发生了外边距折叠现象 -->
<script>
const div = document.querySelector('div')
const p = document.querySelector('p')
console.log(div.offsetLeft);//108,body有个8px的外边距
console.log(p.offsetLeft)
</script>

17. 日期对象

1. 实例化

实例化日期对象:代码中发现new关键字,创建一个时间对象并获取时间

<script>
const date = new Date()//获得当前时间
console.log(date);
//指定时间:例如指定时间结束
const date1 = new Date('2008-1-1')//字符串
console.log(date1);
</script>

2. 日期对象方法

日期对象返回的数据不能直接用,转换为开发常用格式。

<script>
const date = new Date()//实例化日期对象!
console.log(date.getFullYear());//4位年份
console.log(date.getMonth());//0---11
console.log(date.getDate());//getDate获得月份的每一天
console.log(date.getDay());//getDay是获得星期:0---6
console.log(date.getHours());//0---23
console.log(date.getMinutes());//0---59
console.log(date.getSeconds());//0---59
</script>

显示到页

<div></div>
<script>
const div = document.querySelector('div')
function getMyDate() {
const date = new Date()//实例化日期对象!
let m = date.getMonth()+1
let h = date.getHours()
m = m<10 ? '0'+m:m
h = h<10 ? '0'+h:h
return `${date.getFullYear()}年${m}月${date.getDate()} ${h}--${date.getMinutes()}`
}
div.innerHTML = getMyDate()
</script>

简易

<div></div>
<script>
const div = document.querySelector('div')
const date = new Date()
// div.innerHTML = date.toLocaleString()//年月日,时间
// div.innerHTML = date.toLocaleTimeString()//时间
// div.innerHTML = date.toLocaleDateString()//年月日
setInterval(function (params) {
const date = new Date()
div.innerHTML = date.toLocaleString()
},1000)
</script>

3. 时间戳

1970起始的第00秒至今的毫秒数,特殊的计量时间方式

某些场景计算倒计时效果,需要时间戳完成(时间不方便直接相减)

将来的时间戳-现在的时间戳 = 剩余时间毫秒数

+new Date() / Date.now() / getTime()

<script>
//+new Date()
console.log(+new Date());//无需实例化
//getTime()
const date = new Date()//实例化
console.log(date.getTime());
//Date.now()
console.log(Date.now());//无需实例化,但是相对前两者可以返回指定的时间戳,Date.now()只能返回当前的

console.log(+new Date('2023-5-1 00:00:00'));
arr = ['sunday','1','2','3','4','5','6']
// const date = new Date()//
console.log(arr[new Date().getDay()]);//省略了76
</script>

18. 节点操作

1. DOM节点

DOM树里每一个内容都是一个节点

类型: 1元素节点✨:所有的标签:body,h,div; html是根节点

2属性节点:所有的属性:href,id,class,content...

3文本节点:所有的文本:文本,标题,链接名...

2. 查找节点

用的是属性(无需括号)

通过关系(父,子,兄弟)获取元素,例如点击按钮关闭图片,可以直接关闭父级元素。

返回的仍是对象

1. 父节点:.parentNode

返回最近一级的父节点,找不到返回为null

<div class="dad"><div class="son"></div></div>
<script>
const son = document.querySelector('.son')
console.log(son);//返回dom对象
console.log(son.parentNode.parentNode);//返回dom对象
</script>

eg:点击关闭广告

<div class="ad" style="width: 400px;
height: 150px; overflow: hidden ; text-align: center; margin-bottom: 10px;">
<div class="close" style="width: 10px;
height: 10px; float: right; margin: 10px 10px;"></div>
<span style="display: block; color: black; font-size: 30px; margin-top: 60px; line-height: 100%;">advertsment</span>
</div>
<div class="ad" style="width: 400px;
height: 150px; overflow: hidden ; text-align: center; margin-bottom: 10px;">
<div class="close" style="width: 10px;
height: 10px; float: right; margin: 10px 10px;"></div>
<span style="display: block; color: black; font-size: 30px; margin-top: 60px; line-height: 100%;">advertsment</span>
</div>
<div class="ad" style="width: 400px;
height: 150px; overflow: hidden ; text-align: center; margin-bottom: 10px;">
<div class="close" style="width: 10px;
height: 10px; float: right; margin: 10px 10px;"></div>
<span style="display: block; color: black; font-size: 30px; margin-top: 60px; line-height: 100%;">advertsment</span>
</div>
<script>
const close = document.querySelectorAll('.close')
for (let i = 0; i < close.length; i++) {
close[i].addEventListener('click',function (params) {
this.parentNode.style.display='none'
})
}//✨只能为单个元素添加监听器,因此需要用循环遍历数组,给每一个添加事件监听器。
</script>
2. 子节点 .children/childNodes

获得所有元素节点,返回伪数组!

childNodes:获得所有子节点,包括文本节点(空格,换行),注释节点等

3. 兄弟节点

previousElementSibling/nextElementSibling:上一个/下一个

<ul>
<li><p>content</p></li>
<li><p>222</p></li>
<li></li>
<li></li>
<li></li>
</ul>
<script>
const ul = document.querySelector('ul')
console.log(ul.children);
const li2 = document.querySelector('ul li:nth-child(1)')
console.log(li2);
</script>

3. 增加节点(创建&增加)

点击发布按钮,新增一条信息————创建一个新的节点,将其放入指定的元素内部

1. 创建节点

document.createElement('tagName')

2. 追加节点

插入到父元素的最后一个子元素:父元素.appendChild(要插入的元素)

插入到父元素的某个子元素前面:父元素.insertBefore(要插入的元素,在哪个元素前面)

<ul><li>old</li></ul>
<script>
const div = document.createElement('div')//创建节点
console.log(div);
document.body.appendChild(div)
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.innerHTML = 'new'
ul.insertBefore(li,ul.children[0])//返回的是伪数组
</script>
3. 复制节点

复制一个(元素.cloneNode(布尔值)),放入指定元素的内部

深克隆:ture,全部克隆过来;浅克隆:false(空)仅克隆标签

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const ul = document.querySelector('ul')
const li1 = ul.children[0].cloneNode(true)//克隆了
console.log(li1);
ul.appendChild(li1)//放入
ul.appendChild(ul.children[0].cloneNode(true))//复合写法
</script>

4. 删除节点

原生dom中,删除元素必要要通过父元素删除。(父元素.removeChild(要删的元素))

  1. 如果不存在父子关系则删除不成功;

  2. display:none隐藏节点但仍存在;删除就是在html里删除。

<ul>
<li>delate</li>
</ul>
<script>
const ul = document.querySelector('ul')
// const li = document.querySelector('li')
// ul.removeChild(li)
ul.removeChild(ul.children[0])//无需获取li
</script>

19. M端事件(移动端的触屏事件)

touchstart:触摸DOM元素

touchmove:滑动在DOM元素

touchend:从DOM上移开

<div style="width: 300px;
height: 300px; "></div>
<script>
const div = document.querySelector('div')
div.addEventListener('touchstart',function () {
console.log('1');
})
div.addEventListener('touchmove',function () {
console.log('2');
})
div.addEventListener('touchend',function () {
console.log('3');
})
</script>

20.bom(window object):浏览器对象模型

1.bom

  1. bom包含dom,除dom之外还有navigetor,location,history,screen

  2. window对象是全局对象,document,alert(),console.log()都是window的属性,基本bom的属性和方法都是window的

  3. 所有定义在全局作用域中的变量,最后都会变为window对象的属性与方法

  4. window对象下的属性和方法调用的时候可以省略window:可以直接使用 setTimeout() 方法,而不必写成 window.setTimeout()。但是在某些情况下,为了避免变量名或函数名与其他作用域下的同名变量或函数冲突,最好使用 window. 前缀来显式地指定使用的是全局作用域下的属性或方法。

<script>
console.log(document===window.document);//1.b
console.log(alert===window.alert);

function fn() {
console.log(1);
}
window.fn()
var num = 10//var是作用在全局作用域上的,等价于在window对象上创建一个属性num,其值为10
console.log(window.num);//任何地方都可以通过 window.message 来访问这个变量。这种方式也说明了为什么全局变量会对整个应用程序产生影响,因为它们实际上是全局对象的属性,可以被任何代码访问和修改。
</script>

2.定时器-延时函数

js内置了一个用来让代码延迟执行的函数(只执行一次),setTimeout(回调函数,毫秒)

清除: clearTimeout(timer)

  1. 延时器需要等待,所以后面的先执行;

  2. 每一次调用定时器都会产生一个新的延时器

<script>
setTimeout(function () {
console.log(1);
},1000)

let timer = setTimeout(function () {
console.log(2);
},1000)
clearTimeout(timer)
</script>

3.js执行机制:单线程(同步&异步)

同步:先a再b再c:同步任务都在主线任务上进行,形成一个执行栈

异步:在a的同时b,c:js的异步是通过回调函数实现的,一般而言,异步任务有以下三种类型:

  1. 普通事件:click,reize...

  2. 资源加载:load,error...

  3. 定时器:setInterval,setTimeout...

异步任务添加到相关任务队列(消息队列)中

机制:

  1. 先执行执行栈中的同步任务

  2. 异步任务放入任务队列中。

  3. 一旦执行栈中的所有同步任务执行完毕,系统会按照顺序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

4.location对象

数据类型是对象,它拆分保存了url地址的各个组成部分。

常用属性方法:href属性获取完整的url地址,对其赋值时用于地址的跳转。

1. 'location.href'自动跳转
<script>//a---'location.href'
console.log(location);//可以省略window
console.log(location.href)
//href 经常用href 利用js的方法跳转页面
//location.href = 'http://www.bing.com'// 直接跳转
const a = document.createElement('a')
document.body.appendChild(a)//别写错了成string

let i=5
a.innerHTML = `<a href="http://www.bing.com">${i}</a>`
let timerID = setInterval(function () {
i--
a.innerHTML = `<a href="http://www.bing.com">${i}</a>`
if (i===0) {
location.href = 'http://www.bing.com'
clearInterval(timerID)// 欲终止计时器,要先定义timerID,才能在clearInterval()里终止
}
},1000)
</script>
2. 'search'

search属性获取地址中携带的参数,url中符号?后面的部分

form里name属性必须要写!

点击了button之后,网页地址栏?后面会带有输入的信息,通过search属性获取

<form action="">
<input type="text" name="username">
<input type="password" name="psd">
<button>submit</button>
</form>
<script>
console.log(location.search);
</script> -->
3. 'hash'

看url变化

4. 'reload'方法
<a href="#/my">my</a>
<a href="#/friend">friend</a>
<a href="#/download">download</a>
<button class="reload">reflesh</button>
<script>
//在控制台输入location.hash
const reload = document.querySelector('.reload')
reload.addEventListener('click',function () {
location.reload()
})
</script>

5.navigate对象

数据类型是对象,该对象记录下了浏览器自身的相关信息。

常用属性方法:userAgent:检测浏览器的版本及平台。

<script>//控制台点击移动端刷新自动跳转,能复制就行
// 检测 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://www.bing.com'
}
})();

//这是各种匿名函数写法
// (function () { })();
// !(function () { })();
// ~function () { }();
!function () { }()
</script>

6.history对象

数据类型是对象,主要管理历史记录,该对象与浏览器地址栏的操作相对应,如前进,后退。历史记录等。

常用属性方法:back()可以后退, forward()前进, go(参数)(1前进一个页面,-1后退一个页面)

<button>backward</button>
<button>forward</button>
<script>
const backward = document.querySelector('button:first-child')
const forward = backward.nextElementSibling
backward.addEventListener('click',function () {
hiatory.back()
})
forward.addEventListener('click',function () {
history.go(1)
})
<script>

21. 事件循环(event loop)

主线程不断的重复获得任务,执行任务,再获取任务,在执行,这种机制被称为事件循环。

这个过程先执行栈,然后任务队列,哪个异步任务结束了就放到执行栈里面去;结束之后又先看执行栈,没有再看任务队列,这个就叫做事件循环。而在看哪个异步完成了这个操作不是js操作,因为js单线程;而是浏览器来操作,观察哪个任务结束了就放进执行栈

<script>
console.log(1);
setTimeout(function () {
console.log(2);
},2000)
setTimeout(function () {
console.log(3);
},0)
console.log(4);

</script>

22. 本地存储localstorage

将数据存储在本地,基于HTML5的规范 (理解为小型的仓库,数据库)

  1. 数据存储在用户浏览器中

  2. 设置,读取方便,甚至页面刷新不读取数据

  3. 容量较大,sessionStorage localStorage约5M作用

1. localStorage

将数据永远保存到本地(用户的电脑),除非手动删除,否则关闭页面也会存在。

特性: 同一浏览器可以共享;以键值对的形式存储使用;本地存储只能存储string

语法: locakStorage.setItem('key'.'value') 括号内键值对

<script>//元素---application---local storage
//storage a name: uname;tom
localStorage.setItem('uname','tom')
localStorage.setItem('age',18)//数字不用''
//获取, 只需要名字
console.log(localStorage.getItem('uname'));
console.log(localStorage.getItem('age'));//取出是string
//删除,只删除名字
localStorage.removeItem('uname')
//改,如原来有这个键是改,没有就是增
localStorage.setItem('uname','peter')
</script>

2. sessionstorage

特点:生命周期为关闭浏览器窗口;

同一个窗口(页面)数据可以共享;

以键值对的形式存储使用;

用法和localstorage基本相同

3. 存储复杂数据类型

本地只能存储字符串,无法存储复杂数据类型

复杂数据类型必须 转换成json字符串,再存储到本地:JSON.stringify(复杂数据类型)

使用JSON.stringify()方法将JSON对象转换为JSON字符串,也可以使用JSON.parse()方法将JSON字符串转换为JSON对象。

JSON对象和JSON字符串都是用来表示和交换数据的,它们之间可以相互转换,但是JSON字符串是一个字符串类型的数据,而JSON对象则是JavaScript原生的对象类型,

<script>
const obj = {
uname: 'tom',
age: 18,
gender: 'male '
}
//尝试:第一个是键!第二个值是变量
// localStorage.setItem('obj',obj)//这样直接存无论在console还是application结果都是[object object]
// console.log(localStorage.getItem('obj'));

//a.使用JSON.stringify()方法将复杂数据类型转换为JSON字符串
localStorage.setItem('obj',JSON.stringify(obj))
console.log(localStorage.getItem('obj'));
//JSON对象:{"uname":"tom","age":18,"gender":"male "} (JSON字符串)属性和值全都有 双引号!

//b.使用JSON.parse将JSON字符串转化为 对象
console.log(JSON.parse(localStorage.getItem('obj')));
</script>

23. 字符串拼接方法:map();join()

1. map():

遍历数组处理数据,并且返回新的数组。

map: 映射:两个元素的集互相映射的关系,map重点有返回值,forEach没有返回值。

想要遍历数组用forEach,得到新数组用map

<script>
const arr = ['red','blue','yellow']
const newArr = arr.map(function (ele,index) {
console.log(ele);
console.log(index);
return ele+' color'
})
console.log(newArr);
</script>

2. join()

将数组中所有元素转化为一个字符串。

数组元素是通过参数里面指定的分隔符进行分割的,空字符串(''),则所有元素之间间隔没有任何字符。

<script>
const arr = ['red','blue','yellow']
console.log(arr.join(''));
console.log(arr.join());//在console中进行对比,不要间隔用''
</script>

组合使用map();join()方法渲染页面

map()遍历数组数据生成tr,返回一个数组

24. 正则表达式

1. 介绍

正则表达式(Regular Expression)用于于匹配字符串中字符组合的模式;js中,正则表达式也是对象

通常用来查找,替换那些复合正则表达式的文本,许多语言都支持正则表达式。

eg:在一群人中找出戴眼镜戴帽子的男人,通过这些信息找到精确的人,这些用于查找的描述,信息编写一个模式,对应 到计算机中就是正则表达式。

使用场景:

  1. 验证表单(匹配):例如用户名只能输入字母数字下划线;

  2. 昵称只能输入中文;

  3. 敏感词替换(替换)

  4. 从字符串中提取特定部分(提取 )

2. 语法(2种)

a.定义规则;b.根据规则去查找,找到则返回

定义正则表达式语法:const 变量名 = /表达式/ ('/ /'是正则表达式字面量)

test()方法:判断是否有符合规则的字符串;用来查看正则表达式和指定的字符串是否匹配。匹配返回ture,否则返回false 。

exec()方法:在一个指定字符串中执行一个搜索匹配:regObj.exec(被检测字符串),匹配成功返回一个数组,否则返回null。

<script>
const str = '1234566543478876543456788765433456'
//无需引号,写什么查什么
const reg = /6/
console.log(reg.test(str));//匹配返回ture,否则返回false
console.log(reg.exec(str));
</script>

3. 元字符

普通字符:仅能描述本身,例如字母数字,普通字符只能匹配字符串中相同的字符;

元字符(特殊字符):具有特殊含义的字符,极大的提高了灵活性与匹配功能:

26个字母a,b,c,...,y,z换成元字符写法: [a-z]

元字符分类:

  1. 边界符:表示位置,开头和结尾,必须用什么开头,用什么结尾

  2. 量词:表示重复次数

  3. 字符类:比如\d表示0-9

1. 边界符

提示字符所处的位置

^:表示匹配行首的文本,以谁开始 $:表示匹配行尾的文本,以谁结束

<script>
//元字符
console.log(/a/.test('caba'));//ture
//边界符
console.log(/^a/.test('aaa'));//ture
console.log(/^a/.test('cba'));//false
console.log(/^a$/.test('a'));//ture同时以a开头结尾,注意写法,仅此为ture,其余全是false,原因如下
console.log(/^a$/.test('aa'));//false同时以a开头结尾的a必须是同一个a!!!
</script>
2. 量词

设定某个量词出现的次数,n的逗号绝对不能有空格

*: 重复0次或更多次;[0,]

+:重复1次或更多次;[1,]

?:重复0次或1次;[0,1]

{n}:重复n次;写几次就必须重复几次

{n,}:重复n次或更多次;

{n,m}:重复n-m次;

<script>
console.log(/^a$/.test('abcbabcba'));//false
console.log(/^a*$/.test(''));//ture
console.log(/^a*$/.test('abcbabcba'));//false:想要ture字符串中只能有0或多个a,不能有其他的!!!!!

console.log(/^a+$/.test('abcbabcba'))//false
console.log(/^a+$/.test(''))//false

console.log(/^a?$/.test('aa'))//false

console.log(/^a{4}$/.test('aaaa'))//ture
console.log(/^a{4}$/.test('aaaaa'))//false
</script>
3. 字符类

[] 匹配字符集合;eg;[abc]后面的字符串只要包含abc任意一个字符(!!!只选一个!!!),都返回ture, 等同a||b||c

'-'连字符:表示一个范围,[a-z]:26个小写字母都可以;[a-zA-Z]:大小写都可以;[0-9]:0-9的数字都可以

/^1-9{4,}$/(号码从10000开始)

[^] 取反:在[]内加上^代表除去[]内的字符都可以

<script>
console.log(/[abc]/.test('jafj'));//ture
console.log(/[abc]/.test('jAfj'));//false

console.log(/^[abc]$/.test('ab'));//false(只选一个!!!)
console.log(/^[abc]{2}$/.test('ab'));//ture

console.log(/^[a-z]$/.test('f'));//ture
console.log(/^[a-z]$/.test('F'));//false
console.log(/^[a-zA-Z0-9]$/.test('f'));//ture
console.log(/^[a-z][A-Z][0-9]$/.test(3));//false:判断字符串是否由三个字符组成,并且这三个字符必须依次是小写字母、大写字母和数字。
console.log(/^[1-9][0-9]{4,}$/.test(12345));//ture
//^ 匹配字符串的开头
//[1-9] 匹配1-9中的一个数字
//[0-9]{4,} 匹配至少4位数字,即数字的长度至少为5位
//$ 匹配字符串的结尾
</script>
<script>
const input = document.createElement('input')
const span = document.createElement('span')
input.setAttribute('type','text')
document.body.appendChild(input)
document.body.appendChild(span)
input.addEventListener('blur',function () {
let tf = /^[a-zA-Z0-9-_]{6,16}$/.test(input.value)
if (tf===true) {
span.innerHTML= 'ture'
}else{
span.innerHTML = 'false'
}
})
</script>
4. 预定义

某些常见方式的简写方式

[0-9]: \d

[^0-9]: \D

[a-zA-Z0-9-_]: \w

[^a-zA-Z0-9-_]: \W

[\t\r\n\v\f]: \s: 匹配空格(包括制表符,回车符,换行符,垂直制表符,换页符)

[^\t\r\n\v\f]: \S: 匹配非空格的字符

<script>
const input = document.createElement('input')
const button = document.createElement('button')
document.body.appendChild(input)
document.body.appendChild(button)
button.innerHTML='111'
button.addEventListener('click',function () {
console.log(/^[12]\d{3}[01]\d[0123]\d/.test(input.value));//不能加框
input.value = ''
})
</script>

5. 修饰符

/表达式/修饰符

i: ignore :正则匹配时不区分大小写

g: global :匹配所有满足表达式的结果

replace:替换 : 字符串.replace(/正则/,'替换的文本')

<script>
console.log(/^abcd$/i.test('ABCD'));

let str = 'abaBaBaba'//不能发生改变
str = str.replace(/b|B/g,'a')//正则里或者只要一条!虽然使用了 str.replace() 函数,但是并没有对 str 进行重新赋值,所以 str 的值仍然是原来的字符串 'abaBaBaba'。需要将 str.replace() 的结果重新赋值给 str 才能改变 str 的值。
let str1 = str.replace(/b/ig,'a')//i是忽略大小写,一次只能替换一个,所以用'g'全部替换,'ig''gi'皆可;
console.log(str);
console.log(str1);
</script>

Js---------------------------------

1.作用域

scope 规定了变量访问的范围

1. 局部作用域:函数作用域,块作用域

1. 函数作用域
  1. 函数内部内部声明的变量,外部无法直接访问

2. 函数的参数也是函数内部的局部变量

3. 不同函数内部声明的变量无法相互访问

  1. 函数执行完毕后,函数内部的变量实际被清空了

2. 块作用域

在js中用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将 '有可能' 无法被访问

  1. 'let'声明的变量会产生块作用域, 'var'不会产生块作用域。

2. const声明的常量也会产生块作用域。

3.不同代码块之间的变量无法互相访问。 //因此多个循环都可以用let i=0声明变量。

4.用let&const

<script>
for (let i = 0; i < 3; i++) {
console.log(i);
}
for (var j= 0; j < 3; j++) {
console.log(j);
}
console.log(j);//var不会产生块作用域,所以 {} 外依然能被访问
</script>

2. 全局作用域

<script>标签和 .js文件的 '最外层' 即全局作用域,在此声明的变量在任何其它作用域可以被访问。

1.为window对象动态添加的属性默认也是全局的,不推荐!

2.函数中未使用任何关键字声明的变量为全局变量,不推荐!

3.为防止全局变量被污染,少声明全局变量。

3. 作用域链: 本质是底层的 变量查找机制

  1. 函数被执行时,会优先在当前作用域查找变量。

  2. 若当前差不到则会依次查找父级作用域直到全局作用域.

  3. 嵌套关系的作用域串联起来成了作用域链。

  4.  

  5. 子作用域可以访问父作用域,父作用域不能访问子作用域。

4. js垃圾回收机制GC(Garage Collection)

js中 '内存' 的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收

内存的生命周期:
       1. 内存分配:当我们声明变量,函数,对象的时候,函数会自动为它们分配内存。
1. 内存使用:即读写内存,也就是使用变量,函数等。
1. 内存回收:使用完毕,由 '垃圾回收器' 自动回收不再使用的内存。

说明:

1. 全局变量一般不会被回收(关闭页面回收)。

2. 一般局部变量不用了会自动回收掉。

内存泄漏:程序中分配的 '内存' 由于某种原因程序 '未释放' 或 '无法释放' 叫做内存泄漏

js回收机制的算法说明

堆栈空间分配区别:

栈(操作系统): 由 '操作系统自动分配释放' 函数的参数值,局部变量等,基本数据类型放到栈里面。

堆(操作系统): 一般由程序员分配释放,否则由 '垃圾回收机制' 回收。'复杂数据类型' 放到堆里面。

tips:复杂数据类型赋值赋的是地址。

两种常用的垃圾回收算法:

  1. 引用计数法(IE)(已弃用):定义'内存不再使用',看一个'对象'是否有指向它的引用,没有引用了就回收对象。

    算法:

a. 跟踪记录被引用的次数;b. 如果减少引用它的次数则’-1‘;c. 如果引用次数是1,则释放内存。

eg: 一个数组const arr = [1,2,3,4],'数组也属于对象',属于'复杂数据类型',变放入'堆'里面,为了找到这个数组,便在'栈里面存放这个数组的地址',于是arr可以通过地址找到数组,同时栈里面的地址指向了数组,那么引用次数记录为1;代码又往下读到 arr = null,null属于简单数据类型,内存里没有地址了,不指向数组了,没有被引用了那么引用次数变为了0,就自动回收了。

缺点:嵌套引用(循环引用):两个对象 '互相引用',它们的引用次数永不为0,即便它们不再使用,也不会回收进而导致内存泄漏。

2. 标记清除法:

a. 标记清除法将不再使用的对象,定义为'无法到达的对象'。

b. 从'根部'(js中就是全局对象)出发定时扫描内存中的对象,凡是能从'根部到达'的对象,都是还需要使用的。

c. 那些无法从根部出发触及到的'对象被标记'为不再使用,稍后'进行回收'。

5. 闭包

概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域。

闭包 = 内层函数 + 外层函数的变量

一个函数能访问另一个函数的作用域。

作用:封闭数据,提供操作,外部也可以访问函数内部的变量。

<script>
function fn() {
const a=1
function g() {
console.log(a);//断点调试,scope(作用域)显示闭包(Closure)
}
g()
}
fn()
</script>
<script>//常见闭包的形式,外部可以访问内部的变量
function outer() {
let i=1
function fn() {
console.log(i);
}
return fn//outer() === fn === function fn(){}
}
const g = outer()//const g = function fn(){}
g()//fn,g是函数本身;fn()是函数的结果。
</script>

应用:实现数据的私有,无法直接修改i,但是一旦i不会,就会导致 '内存泄露'。

eg:统计函数的调用次数,

<script>//这里i是全局变量,很容易被修改
let i=0
function fn() {
i++
console.log(i);
}
</script>
<script>
function outer() {
let i = 0
function fn() {
i++
console.log(i);
}
return fn
}
const fun = outer()//因为fun是全局作用域,因此只有关闭时才会被回收,fun指向了fn函数,fn使用了i,从global可以一路找到i,因此虽然i在局部作用域里,但是不会被回收。
</script>

6. 变量提升

仅对于用var声明变量,它允许在变量声明之前即被访问。

代码执行之前,会在'当前'作用域之下所有var声明的变量提升到'当前'作用域的最前面(只提升声明,不提升赋值)

注意:

  1. 变量在未声明即被访问会报语法错误

  2. 变量在var声明之前即被访问,变量的值为undefined

  3. let/const声明的变量不存在变量提升

  4. 变量提升发生在相同作用域中

<script>
//var a //代码执行之前,会在'当前'作用域之下所有var声明的变量提升到'当前'作用域的最前面(只提升声明,不提升赋值)
let c
console.log(c);
console.log(a);//undefined
console.log(b);//error
var a = 1
let b = 2
</script>

2. 函数进阶:

函数参数默认值,动态参数,剩余参数的使用细节,提升函数应用的灵活度,箭头函数

1. 函数提升

a. 会把所有函数声明提升到'当前'作用域的最前面

b. 只提升函数声明,不提升函数调用

c. 函数表达式必须先赋值声明,后调用,否则会报错。

<script>
// fn()
// function fn() {
// console.log(1);
// }

var fun//提升变量声明,没提升赋值
fun()//因为只提升了声明,都不知道fun是个函数
fun = function () {
console.log('函数表达式');
}
</script>

2. 函数参数

动态参数

arguments:函数内部内置的'伪数组'变量,它包含调用函数时传入的所有实参,它只存在于函数中。

<script>
function getSum() {
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
console.log(sum);
}
getSum(1,2,3,4,5)
getSum(4,5,6,32,543,6)
</script>
剩余参数(主用)

将一个不定数量的参数表示为一个数组:‘ ...数组名 ’

a. '...' 是语法符号,置于最末函数形参之前,用以获取多余的参数

b. 借助'...'获取的剩余实参,是个'真数组'

<script>
function getSum(a,b,...arr) {//可以用于允许用户至少输入几个
console.log(arr);
}
getSum(2,4,5,3,6,4,5,4,3,3)
</script>
补充:展开运算符:将一个数组进行展开

说明:

a. 不会修改原数组

b. 应用场景:求最大最小值,合并数组。

<script>
const arr = [1,2,3,4,5]
//在console里没有逗号,而实际上: ...arr === 1,2,3,4,5
console.log(...arr);
console.log(Math.max(1,2,3));//求最大值里面不是数组,还需要用,隔开
console.log(Math.max(...arr));
//合并数组
const arr2 = [6,7,8]
const arr3 = [...arr,...arr2]
console.log(arr3);
</script>

对比:剩余参数:函数参数使用,得到真数组。

展开运算符:数组中使用,数组展开。

3. 箭头函数

更简洁的函数写法,且不绑定this

箭头函数不是替代,而是更适用于那些本来'需要匿名函数的地方'

1. 基本语法

a. 箭头函数属于表达式函数,因此不存在函数提升。

b. 箭头函数只有一个参数时可以省略()

c. 箭头函数只有一行代码时可以省略{},无需return自动为返回值做返回。

d. 加括号的函数体返回对象字面量表达式。

<script>
//普通函数
// function fn() {
// console.log(1);
// }

//a. 箭头函数基本语法
const fn = () => {
console.log(1);
}
fn()

//b. 传入形参实参
const fn1 = (a) => {
console.log(a);
}
fn1(2)

//c. 只有一个形参省略()
const fn2 = a => {
console.log(a);
}
fn2(3)

//d. 只有一行代码省略大括号
const fn3 = a => console.log(a);
fn3(4)

//e. 只有一行代码省略return
// const fn4 = a => {
// return a+1
// }
// console.log(fn5(1));
const fn4 = a => a+1
console.log(fn5(1));

//阻止表单默认提交,省略大括号小括号
// const form = document.querySelector('form')
// form.addEventListener('click', e => e.preventDefault())

//f.箭头函数可以直接返回一个对象
const g = (uname) => ({uname: uname })//里面{}是对象的,外面再包{}易混淆,故({}),数组解构之后可以({uname})
fn('tom')
</script>
2. 箭头函数参数

箭头函数有剩余函数...数组名, 没有动态参数

<script>
//利用箭头函数求和
const getSum = (...arr) => {
let sum=0
for (let i = 0; i < arr.length; i++) {
sum+=arr[i]
}
console.log(sum);
}
getSum(2,3,4)
</script>
3. 箭头函数this

箭头函数不会创建自己的this,它只会从自己的作用域链的上一次层沿用this

箭头函数没有自己的this值,所以它会继承外部的this值

普通函数的this值是在运行时根据函数调用的方式动态确定的,它可以根据函数的调用者不同而指向不同的对象。

dom事件回调函数不推荐箭头函数,尤其需要this。

普通函数的this
<button></button>
<script>
console.log(this);// 指向window

const f1 = function () {
console.log(this);//指向window,因为写全是window.f1,指向this的调用者
}
f1 ()

const btn = document.querySelector('button')
btn.addEventListener('click',function () {
console.log(this);//当前this指向btn
})

const obj = {
name:'a',
fn2:function () {
console.log(this);//指向obj
}
}
obj.fn2()
</script>
箭头函数的this

父级作用域的this值决定。

this所在的局部作用域没有指向,而确实指向window并不是因为window是调用者,而是它作用域链的上一层<script>的this指向的是window

<script>
//普通箭头函数this
const fn = () => {console.log(this);}
fn()

//对象方法的箭头函数this
const obj = {
name:'a',
fn2:() =>{console.log(this)}//指向window,window.obj.fn2()
}
obj.fn2()

const obj2 = {
name:'a',
fn2: function () {
console.log(this);//普通函数this指向调用者obj2
let i=1
const count = () => {
console.log(this);//箭头函数本身局部作用域没this,上一级作用域this指向obj2
}
count()
}
}
obj2.fn2()
</script>

3. 解构赋值

语法分类,使用解构简洁语法快速为变量赋值

1. 数组解构

将数组的单元值(数组元素)'批量' 赋值给一系列变量的简洁语法

基本语法:赋值运算符 = 左侧的[]用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量

基本
<script>
const arr = [100,20,60]

const [] = arr
//const [max,min,avg] = arr
const [max,min,avg] = [100,20,60]
console.log(max);

//交换变量
let a=1
let b=2;//[a,b]q前必须要分号!
[a,b] = [b,a]
console.log(a,b);
</script>
js前必须加分号情况
  1. 立即执行函数:(function({}))();

  2. 数组解构:数组开头,前面有语句,必须加分号

<script>
//如若没有分号,就不认为数组换行,而是跟在上一行句子后面,
const c = 1
;[1,2,3].map(function (item) {
console.log(item);
})
</script>
语法
<script>
// 变量多,单元值少
const [a1,b1,c1,d1] = [1,2,3]
console.log(d1);//undefined

// 变量少,单元值多
//用剩余参数,!!!剩余参数只能于最后位。
const [a2,b2,...arr] = [1,2,3,4,5]
console.log(arr);

//防止undefined传递
//类似默认参数
const [a3=0,b3=0] = []

//按需导入,忽略某些返回值
const [a4,,c4,d4] = [1,2,3,4]

//多维数组
const arr1 = [1,2,[[3,4],5]]
console.log(arr1[2][0][1]);//得到4
const [a5,b5,c5] = arr1

console.log(c5);//[[3,4],5]
const [a6,b6,[c6,d6]] = arr1
console.log(c6);//[3,4]
</script>

2. 对象解构

将对象的属性和方法快速批量快速赋值给一系列变量的简洁语法

基本语法

a. 赋值运算符 = 左侧的{}用于批量声明变量,右侧对象的属性值将被复制给左侧的变量。

b. 对象属性的值将被赋给与属性名'相同'的变量

c. 注意解构的变量名不要和外面的变量名冲突否则报错

d. 对象中找不到与变量名属性一致的属性时变量值为undefined

//normal
const obj = {
uname:'tom',
age: 10
}
对象解构

const{uname,age} = {uname:'tom',age: 10}//变量名和属性名必须相同

等同 const uname = obj.uname

更改对象解构的变量名(如若已经有变量名为uname)

const obj1 = {
newname:'tom',
age: 10
}
const newname = 1//对象解构的变量名就不能为newname了,age与上个变量名也有冲突,都需重新命名
const {newname:name1,age:age1} = obj1
数组对象解构
const abc = [//对象放数组里
{
uname: 1,
age:2
}
]
const [{uname:name2,age:age2}] = abc
console.log(name2,age2 );
多级对象解构
const obj2 = {
a1:1,
b1:{
b2:2,
b3:3,
b4:4
},//这里要','
c1:5
}
const {a1,b1:{b2,b3,b4},c1} = obj2
案例:后台真实数据
<script>//对象所有的全都加了"",这个叫做json对象,通过ajax发送过来的数据都是这个格式
const msg = {
"code": 200,//code200经常表示请求成功
"msg": "获取新闻列表成功",//message 返回的一个信息
"data": [ //核心数据都在data里
{
"id": 1,
"title": "5G商用自己,三大运用商收入下降",
"count": 58
},
{
"id": 2,
"title": "国际媒体头条速览",
"count": 56
},
{
"id": 3,
"title": "乌克兰和俄罗斯持续冲突",
"count": 1669
},

]
}
//需求1:解构data信息
const {data} = msg
console.log(data);

//需求2:上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数

//正常写法
// const {data} = msg
// function renden(arr) {
// console.log(arr);
// }
// renden(data)

//更好写法
//const {data} = msg,data就是msg解构而来,因此形参直接{data},传入参数顺便解构
//msg虽然很多属性,但是我们利用解构只要data
function genden({data}) {
console.log({data});
}
genden(msg)


//需求3:为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData
// function renden1({data}) {
// const {data:newData} = msg
// console.log(newData);
// }
// renden1(msg)
function renden1({data:myData}) {
console.log(myData);
}
renden1(msg)
</script>
forEach遍历数组

(for循环加强版)适合遍历数组对象!

遍历数组的每个元素,并将元素传递给回调函数(只遍历,不返回值)(只能遍历数组)

语法:(与map()很类似)

被遍历的数组.forEach(function(当前数组元素,当前元素索引号){
//函数体
})

当前数组元素必写,当前元素索引号可选

<script>
const arr = [1,2,3,4,5,6,7,8]
arr.forEach(function (item,index) {
console.log(item);
console.log(index);
})
</script>

4. 深入对象

创建对象三种方式&&构造函数&&实例成员&静态成员

1. 创建对象三种方式

a.利用对象字面量创建对象。
const dxzml = {
uname:1
}
b.利用new Object创建对象。
const nobj = new Object({uname:2})
nobj.uname = 3
console.log(nobj);
c.利用构造函数创建对象。
function Aaa(bbb,ccc,ddd) {
this.bbc = bbb//给对象添加了一个叫bbc的属性,this是空对象
this.ccd = ccc
this.dde = ddd
}
const abc = new Aaa('dkkd',88,'kjqk')
console.log(abc);

2. 构造函数(实例化)

利用构造函数创建对象。

构造函数:一种特殊的函数,用来初始化对象,公共的抽出来封装到函数里。

场景:常规的{...}语法允许创建一个对象,继续创建还需要重写一遍,此时可以通过'构造函数'来'快速创建多个'类似的对象。

规定:

  1. 名字只能以大写开头;

  2. 他们只能以'new'操作符来执行

说明:

  1. 使用new关键字构造函数的行为被称作'实例化'。

  2. 实例化构造函数时没有参数可以省略()

  3. 构造函数内部无需写return,返回值即为新创建的对象。

  4. 构造函数内部的return返回值无效,因此无需写return。

  5. new Object() ; new Date() 也是实例化构造函数。

<script>
function Goods(name,price,count) {
this.uname = name
this.price = price
this.count = count
}
const a1 = new Goods('mi',1999,20)
const b1 = new Date('2022-08-01')//系统自带的实例化构造函数
console.log(a1,b1);
</script>

实例化执行过程

  1. 创建新对象;

  2. 构造函数this指向新对象;

  3. 执行构造函数代码,修改this,添加新的属性;

  4. 返回新对象

3. 实例成员&静态成员

实例成员

通过构造函数创建的对象称为实例对象,实例对象中的属性和方法被称为实例成员(实例属性和实例方法)

说明:

  1. 为构造函数传入参数,创建结构相同但值'不同的对象'。

  2. 构造函数创建的对象'彼此独立'互不影响。

<script>
//构造函数
function Fn() {
//构造函数内部的this就是实例对象
//实例对象中动态添加属性
this.name = 'tom'
//实例对象动态添加方法
this.showOn = () => console.log(1)
}
//实例化.p1就是实例对象
//p1实际就是构造函数中的this
const p1 = new Fn()
console.log(p1);
console.log(p1.name);//访问实例属性
p1.showOn();//调用实例方法
</script>
静态成员

构造函数的属性和方法被称为静态成员(静态属性和静态方法)

说明:

  1. 静态成员只能构造函数来访问。

  2. 静态方法中的this指向构造函数。比如Date.now() Math.PI Math.Random()

<script>
function Person(name,age) {
this.name = name
}
//静态属性
Person.aaa = 1
Person.bbb = 2
//静态方法
Person.ccc = function() {//箭头函数没有this
console.log(3);
//this 指向Person
console.log(this.bbb);
}
Person.ccc()
</script>

4. 内置构造函数

Object, Array,String,Number

基本数据类型:string,number,boolean,undefined,null

引用类型:object

 

string, boolean, number等基本数据类型也有对象的使用特征,如具有属性和方法;

因为其是js底层使用Object构造函数"包装"来的,称为'包装类型'

 

js中几乎所有的数据都可以基于构成函数创建

<script>
//普通字符串也有属性,甚至有些还有方法
const str = 'string'
const num = 1
console.log(str.length);
console.log(num.toFixed(2));
//虽然是简单数据类型,但是内部是如下实例化,被包装成了对象
//const str = new String('string')
//js底层完成,把简单数据类型包装成了引用数据类型
</script>

引用类型:Object, Array, RegExp(正则表达式), Date等

包装类型:String, Number, Boolean等

Object

常用静态方法:只有构造函数Object才可以调用

Object.keys() 静态方法获取对象中所有属性(键),返回的是一个数组

Object.values() 静态方法获取对象中所有属性

Object.assign(待拷贝的,被拷贝的)静态方法常用于对象拷贝;经常使用的场景给对象添加属性。

    <script>
const o = {name:'tom',age:1}
for(let k in o){//之前这样这样才能获得所有属性名和属性值
console.log(k);
console.log(o[k]);
}

console.log(Object.keys(o));
console.log(Object.values(o));

//对象拷贝
const obj = {}
Object.assign(obj,o)
console.log(obj);
//对象拷贝经常使用的场景给对象添加属性
Object.assign(obj,{value:1000})
console.log(obj);
</script>

Array

Array是内置的构造函数,用于创建数组。

建议使用字面量创建,而非Array构造函数创建

数组常见实例方法:核心方法

forEach: 遍历数组 不返回数组,用于'查找&遍历'数组元素。

filter: 过滤数组 '返回'新数组,返回的是'满足筛选条件'的数组元素。

map: 迭代数组 '返回'新数组,返回的是'处理之后'的数组元素,想要使用返回的新数组。

reduce: 累计器 返回累计处理的结果,经常用于求和等。

    // reduce方法
<script>
//Array构造函数创建array
const arr1 = new Array(3,5)
console.log(arr1);

//reduce 语法
//arr.reduce(function(上一次值,当前值){},初始值)
const arr = [1,2,3,4]

//没有初始值
const total = arr.reduce(function (prev,current) {
return prev+current
})
console.log(total);

//有初始值
const total1 = arr.reduce((prev,current) => prev+current,10)//初始值与之前想加
console.log(total1);

//如果'没有起始值',则'上一次值'以数组的'第一个数组元素的值'
//每一次循环,把'返回值'给作为 下一次循环的'上一个值'
//如果'有起始值',则 起始值作为'上一次值'

//无初始值
//上一次值 当前值 返回值 (第一次循环 )
// 1 2 3
//上一次值 当前值 返回值 (第二次循环 )
// 3 3 6
//上一次值 当前值 返回值 (第三次循环 )
// 6 4 10

//对象的reduce
const arr2 = [{
name: '张三',
salary: 10000
}, {
name: '李四',
salary: 10000
}, {
name: '王五',
salary: 20000
},
]
const total2 = arr2.reduce((prev,current)=>{
console.log(prev);
return prev + current.salary
},0)//初始值一定不能省略
console.log(total2);
//在使用 reduce 函数时,第二个参数是初始值,用于对第一次迭代时的 prev 进行初始化,如果没有初始值,第一次迭代时 prev 会是数组中的第一个元素。如果数组是空的,则没有初始值的 reduce 会报错。在这个例子中,初始值是 0,因为我们要对每个元素的薪水进行求和,如果不设置初始值,则第一次迭代时,prev 会是数组中的第一个对象,而不是一个数字,会导致加法运算无法进行。
</script>
数组其他常见实例方法

join:数组元素拼接为字符串,并返回字符串; join()结果是,隔开 ; join('')结果是无分隔。

find:查找元素,返回符合测试条件的第一个数组元素值,如果没有符合条件的返回undefined,

every:检测数组 所有 元素是否 都 符合指定条件,如果 所有元素 都通过检测则返回ture,否则返回false(空数组返ture),

some:检测数组元素是否符合指定条件,如果 有元素 满足条件则返回ture,否则返回false,

concat:合并两个数组,返回生成新数组,

sort:对原数组单元值排序,

splice:删除或替换原数组单元,

reverse:反转数组,

findIndex:查找元素的索引值

伪数组转化为真数组,静态方法:Array.from()

//find
<script>
//find方法接收一个回调函数,用于查找数组中符合条件的第一个元素。在这个例子中,isCherries函数作为回调函数传入,find方法会依次遍历inventory数组中的每一个元素,并将其作为参数传递给isCherries函数。当传入樱桃对象时,isCherries函数返回true,此时find方法停止遍历,并返回这个对象。如果没有符合条件的元素,则返回undefined。
const inventory = [
{ name: "apples", quantity: 2 },
{ name: "bananas", quantity: 0 },
{ name: "cherries", quantity: 5 },
];

function isCherries(fruit) {
return fruit.name === "cherries";
}

console.log(inventory.find(isCherries));
// { name: 'cherries', quantity: 5 }

const che = inventory.find(function (item) {
console.log(item.name);
return item.name === 'cherries'
})
console.log(che);

const che2 = inventory.find(item=>item.name === 'cherries')
console.log(che2);
</script>
//every
<script>
const arr = [1,2,3,4]
const flag = arr.every(item => item >= 10)
console.log(flag);
</script>
//拼接字符串,写入div
<script>
const spec = {size:'40cm*40cm',color:'hei'}
const div = document.createElement('div')
document.body.appendChild(div)
//思路:获得所有的属性值,然后拼接字符串。Object.values()->得到数组,再join拼接
div.innerHTML = Object.values(spec).join('/')
</script>

String

字符串常见实例方法

length

split('分隔符')将字符串拆分为数组

substring(需要截取的第一个字符的索引[,结束的索引号])字符串截取

startsWith(检测字符串[,检测位置索引号])检测是否以某字符开头

Includes(搜索的字符串[,检测位置索引号])判断一个字符串是否包含在另一个字符串中,根据情况返回true或false

toUpperCase将字母转换为大写

toLowerCase将字母转换为小写

indexOf检测是否包含某字符

endsWith检测是否以某字符结尾

replace替换字符串,支持正则

Match查找字符串,支持正则

split

分隔符指的是字符串中的分隔符!

<script>
const str1 = '1,2,3,4,5'
console.log(str1.split(','));
const str2 = '1-2-3-4-5'
console.log(str2.split('-'));
</script>
substring

substring(需要截取的第一个字符的索引[,结束的索引号])字符串截取

[]内可省略,返回新字符串

<script>
const arr = 'abcdefghijk'
console.log(arr.substring(3));//defghijk
</script>

里面是索引号,从0开始。