JS进阶--JS听到了不灭的回响

作用域

作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问

作用域分为局部和全局

局部作用域

局部作用域分为函数和块

那 什么是块作用域呢?

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

全局作用域

写到script和.js文件的最外层就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问

全局作用域中声明的变量在任何其他作用域中都可以被访问

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

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

3. 尽可能少的声明全局变量,防止全局变量被污染

作用域链

包没错误的,结果是2

作用域链本质上是底层的变量查找机制。

在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域

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

2. 相同作用域链中按着从小到大的规则查找变量

3. 子作用域能够访问父作用域,父级作用域无法访问子级作用域

从小到大捏 

JS垃圾回收机制

什么是垃圾回收机制?

让我们来了解一下内存的生命周期:

内存泄漏是指程序中分配的内存由于某种原因未释放或者无法释放 

总结:

下面对垃圾回收机制做一个算法说明:

堆栈空间分配区别:

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

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

之前都学过,不多说了

垃圾回收算法有两种:引用计数法和标记清除法

引用计数:

IE采用的引用计数算法, 定义“内存不再使用”,就是看一个对象是否有指向它的引用,没有引用了就回收对象

算法:

1. 跟踪记录被引用的次数

2. 如果被引用了一次,那么就记录次数1,多次引用会累加 ++

3. 如果减少一个引用就减1 --

4. 如果引用次数是0 ,则释放内存

 引用计数法也是有一定缺陷的,如果两个对象互相引用,尽管他们不再使用,垃圾回收器也不会进行回收,从而导致内存泄漏

这样的引用不如果很大量,那就会导致大量的内存泄漏

现在的浏览器已经不用引用计数算法了,而是使用标记清除法:

看看小示意图:

不错

标记清除法的核心:从根部扫描对象,能查找到的就是使用的,查找不到的就要回收

闭包

那么问题来了,什么是闭包?

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

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

先来看看代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function outer(){let a =10function fn(){console.log(a)}fn()}outer()</script>
</body>
</html>

这个什么closure(outer)就是闭包的意思 

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

闭包的基本格式:

闭包可以实现数据的私有,比如我们要做统计函数调用次数,调用一次,就++

 

光是这个函数就可以实现对应的功能,可是问题就在于count是一个全局变量很容易被修改

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function fn(){let count = 1function fun(){count++console.log(`函数被调用${count}次`)}return fun}const result = fn()result()result()</script>
</body>
</html>

这样就可以实现数据的私有了,因为没办法直接修改count

 outer = fn = function fn() { }

我们具体解释:

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

闭包:

封闭数据,实现数据私有,外部也可以访问函数内部的变量

闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来

闭包可能引起内存泄漏

变量提升

什么是变量提升?

变量提升是JS中 的一种现象,允许变量在声明致歉就被访问(仅仅存在于var声明变量):

tips:

JS初学者经常花很多时间才能习惯变量提升,还经常出现一些意想不到的bug,正因为如此,ES6 引入了块级作用域, 用let 或者 const声明变量,让代码写法更加规范和人性化

总结:

函数进阶

函数提升

我们学习函数提升的目标是能够说出函数提升的过程

函数提升与变量提升比较相似,是指函数在声明之前就可以被调用

函数 提升:

1、函数提升能够使函数的声明调用 更加灵活

2、函数表达式不存在提升的现象

3、函数提升出现在相同的作用域当中

函数参数

1、产品需求:写一个求和函数

不管用户传入几个实参,都要把和求出来

那么怎么 写形参呢?

有一个东西叫做动态参数:arguments

可以得到传过来的参数,是伪数组

arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>function getSum() {let sum = 0for (let i = 0; i < arguments.length; i++) {sum += arguments[i]}console.log(sum)}getSum(2, 3, 4)</script>
</body></html>

而除了动态参数,其实剩余参数也能解决这个问题:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function getSum(...arr){console.log(arr)}getSum(2,3)getSum(1,2,3)</script>
</body>
</html>

 如果这样的话,那剩余参数和动态参数又有什么区别呢?

其实剩余参数是剩下的参数

...是语法符号,至于最末的函数形参之前,用于获取多余的实参

获取的剩余实参是真的数组

开发中提倡使用剩余参数,可以这样取样:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>function getSum(a, b, ...arr) {console.log(arr)}getSum(2, 3)getSum(1, 2, 3)</script>
</body></html>

总结:

接下来讲一下展开运算符

展开运算符可以将一个数组进行展开

 

它只是进行展开,并不会修改原数组

可以很方便的求数组的最大值最小值,或者合并数组

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const arr = [1,5,3,8,2]console.log(Math.max(...arr))console.log(Math.min(...arr))</script>
</body>
</html>

 展开运算符和剩余参数的区别:

箭头函数

引入箭头函数的目的是更简短的函数写法并且不绑定this,箭头函数的语法比函数表达式更简洁

更适用于那些本来需要匿名函数的地方

基本语法

当函数只有一个形参的时候可以省略小括号:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const fn = x =>{console.log(x)}fn(1)</script>
</body>
</html>

当函数体只有一行代码的时候,可以写到一行上,并且无需使用return(直接返回值)

 

有更加简洁的语法,这是阻止表单的默认提交事件:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const form = document.querySelector('form')form.addEventListener('click',ev=>ev.preventDefault())</script>
</body>
</html>

还有一种语法是:加括号的函数体返回对象字面量表达式

 由于对象的大括号和箭头函数的冲突了,所以拿小括号包裹起来

箭头函数参数

普通函数有arguments动态参数

箭头函数没有arguments动态参数,但是有剩余参数...args

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>// 利用箭头函数求和const getSum = (...arr) => {let sum = 0for (let i = 0; i < arr.length; i++) {sum += arr[i]}console.log(sum)return sum}getSum(2, 3)</script>
</body></html>

就是没有arguments动态参数,但是有剩余参数

箭头函数this

在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值, 非常令人讨厌。 箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this

 在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window,因此 DOM事件回调函数为了简便,还是不太推荐使用箭头函数

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

DOM事件回调函数不推荐使用箭头函数,特别是需要用到this的时候

Ø 事件回调函数使用箭头函数时,this 为全局的 window

解构赋值

数组解构

解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值

数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法

基本语法:

1. 赋值运算符 = 左侧的 [] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量

2. 变量的顺序对应数组单元值的位置依次进行赋值操作

可以这样进行快速的交换两个变量:

看看,这是冒泡排序的简洁写法:

数组解构是将数组的单元值快速批量的赋值给一系列变量的简洁语法

JS前面有必须要加分号的情况:

1.立即执行函数:

2、数组解构

总结:

让我们看看不同的情况吧:

变量的数量大于单元值的数量的时候,多余的变量将被赋值为undefined

还有别的情况:

允许初始化变量的默认值,且只有单元值为 undefined 时默认值才会生效

对象解构

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

基本的语法:

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

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

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

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

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

可以从一个对象中提取变量并且同时修改新的变量名

我们可以通过对象解构给新的变量名赋值:

:表示赋值给谁

让我们看看数组对象的结构:

 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>//这是后台传递过来的数据,请选出data里面的数据方便后面渲染w
const msg = {"code":200,"msg":"获取新闻列表成功","data":[{"id":1,"title":"5G商用自己,三大运用商收入下降","count":58},{"id":2,"title":"国际媒体头条速览","count":56},{"id":3,"title":"乌克兰和俄罗斯持续冲突","count":1669},]
}
function render({data:MyData}){console.log(MyData)
}
render(msg)</script>
</body>
</html>

遍历数组的foreach方法

foreach方法用于调用数组的每个元素,并将元素传递回给参数

 

 tips:

1. forEach 主要是遍历数组

2. 参数当前数组元素是必须要写的, 索引号可选 

适合遍历数组对象 

综合案例

接下来做案例,进行渲染,foreach+对象解构

//1.声明一个空字符串变量先let str = ' 'goodsList.forEach(item => {console.log(item)      //可以得到每一个数组元素对象})

 只有一个参数的箭头函数可以省略小括号

然后我们进行追加,并在html中显示:

//1.声明一个空字符串变量先let str = ' 'goodsList.forEach(item => {// console.log(item)      //可以得到每一个数组元素对象str += `<div class="item"><img src="" alt=""><p class="name">111</p><p class="price">111</p></div>`})document.querySelector('.list').innerHTML = str

艺术就是解构:

 //1.声明一个空字符串变量先let str = ' 'goodsList.forEach(item => {// console.log(item)      //可以得到每一个数组元素对象const {name,price,picture} = item     //解构就是idstr += `<div class="item"><img src="${picture}" alt=""><p class="name">${name}</p><p class="price">${price}</p></div>`})document.querySelector('.list').innerHTML = str

代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>商品渲染</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}.list {width: 990px;margin: 0 auto;display: flex;flex-wrap: wrap;padding-top: 100px;}.item {width: 240px;margin-left: 10px;padding: 20px 30px;transition: all .5s;margin-bottom: 20px;}.item:nth-child(4n) {margin-left: 0;}.item:hover {box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);transform: translate3d(0, -4px, 0);cursor: pointer;}.item img {width: 100%;}.item .name {font-size: 18px;margin-bottom: 10px;color: #666;}.item .price {font-size: 22px;color: firebrick;}.item .price::before {content: "¥";font-size: 14px;}</style>
</head><body><div class="list"><!-- <div class="item"><img src="" alt=""><p class="name"></p><p class="price"></p></div> --></div><script>const goodsList = [{id: '4001172',name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',price: '289.00',picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',},{id: '4001594',name: '日式黑陶功夫茶组双侧把茶具礼盒装',price: '288.00',picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',},{id: '4001009',name: '竹制干泡茶盘正方形沥水茶台品茶盘',price: '109.00',picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',},{id: '4001874',name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',price: '488.00',picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',},{id: '4001649',name: '大师监制龙泉青瓷茶叶罐',price: '139.00',picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',},{id: '3997185',name: '与众不同的口感汝瓷白酒杯套组1壶4杯',price: '108.00',picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',},{id: '3997403',name: '手工吹制更厚实白酒杯壶套装6壶6杯',price: '99.00',picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',},{id: '3998274',name: '德国百年工艺高端水晶玻璃红酒杯2支装',price: '139.00',picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',},]//1.声明一个空字符串变量先let str = ' 'goodsList.forEach(item => {// console.log(item)      //可以得到每一个数组元素对象const {name,price,picture} = item     //解构就是idstr += `<div class="item"><img src="${picture}" alt=""><p class="name">${name}</p><p class="price">${price}</p></div>`})document.querySelector('.list').innerHTML = str</script>
</body></html>

接下来还需要实现一个可以筛选的模块

 筛选数组有一个filter方法

它可以创建一个新的数组,新的数组中的元素是通过检查指定数组中符合条件的所有元素

主要使用场景:筛选数组符合条件的元素,并返回筛选之后元素的新数组

语法:

例子:

filter() 筛选数组

返回值:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组

参数:currentValue 必须写, index 可选

因为返回新数组,所以不会影响原数组

首先做初始的页面渲染

渲染页面 利用forEach 遍历数据里面的 数据,并渲染数据列表

根据 filter 选择不同条件显示不同商品

步骤一和前面相同,不赘述

//渲染函数  封装function render(arr){//声明空字符串let str = ' '//遍历数组 增加字符串arr.forEach(item => {//解构const {name,picture,price} = item str+=` <div class="item"><img src="${picture}" alt=""><p class="name">${name}</p><p class="price">${price}</p></div>`});document.querySelector('.list').innerHTML = str}render(goodsList)

步骤2:

全部代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>商品渲染</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}.list {width: 990px;margin: 0 auto;display: flex;flex-wrap: wrap;}.item {width: 240px;margin-left: 10px;padding: 20px 30px;transition: all .5s;margin-bottom: 20px;}.item:nth-child(4n) {margin-left: 0;}.item:hover {box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);transform: translate3d(0, -4px, 0);cursor: pointer;}.item img {width: 100%;}.item .name {font-size: 18px;margin-bottom: 10px;color: #666;}.item .price {font-size: 22px;color: firebrick;}.item .price::before {content: "¥";font-size: 14px;}.filter {display: flex;width: 990px;margin: 0 auto;padding: 50px 30px;}.filter a {padding: 10px 20px;background: #f5f5f5;color: #666;text-decoration: none;margin-right: 20px;}.filter a:active,.filter a:focus {background: #05943c;color: #fff;}</style>
</head><body><div class="filter"><a data-index="1" href="javascript:;">0-100元</a><a data-index="2" href="javascript:;">100-300元</a><a data-index="3" href="javascript:;">300元以上</a><a href="javascript:;">全部区间</a></div><div class="list"><!-- <div class="item"><img src="" alt=""><p class="name"></p><p class="price"></p></div> --></div><script>// 2. 初始化数据const goodsList = [{id: '4001172',name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',price: '289.00',picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',},{id: '4001594',name: '日式黑陶功夫茶组双侧把茶具礼盒装',price: '288.00',picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',},{id: '4001009',name: '竹制干泡茶盘正方形沥水茶台品茶盘',price: '109.00',picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',},{id: '4001874',name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',price: '488.00',picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',},{id: '4001649',name: '大师监制龙泉青瓷茶叶罐',price: '139.00',picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',},{id: '3997185',name: '与众不同的口感汝瓷白酒杯套组1壶4杯',price: '108.00',picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',},{id: '3997403',name: '手工吹制更厚实白酒杯壶套装6壶6杯',price: '99.00',picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',},{id: '3998274',name: '德国百年工艺高端水晶玻璃红酒杯2支装',price: '139.00',picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',},]//渲染函数  封装function render(arr) {//声明空字符串let str = ' '//遍历数组 增加字符串arr.forEach(item => {//解构const { name, picture, price } = itemstr += ` <div class="item"><img src="${picture}" alt=""><p class="name">${name}</p><p class="price">${price}</p></div>`});document.querySelector('.list').innerHTML = str}render(goodsList)//过滤筛选document.querySelector('.filter').addEventListener('click', e => {const { tagName, dataset } = e.target//判断if (e.target.tagName === 'A') {let arr = goodsListif (dataset.index === '1') {arr = goodsList.filter(item => item.price > 0 && item.price <= 100)}else if(dataset.index === '2'){arr = goodsList.filter(item=>item.price >=100 && item.price <= 300)}else if(dataset.index === '3'){arr = goodsList.filter(item=>item.price >=300)}render(arr)}})</script>
</body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/504334.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MFC读写文件实例

程序功能&#xff1a;点击写入文件按钮将输入编辑框中内容写入以系统时间命名的文件中&#xff0c;点击读取文件按钮将选中的文件内容显示到静态文本控件中。 相关代码如下&#xff1a; void CWR_FILEDlg::OnButton1() {CString str;GetDlgItem(IDC_EDIT1)->GetWindowText…

IWOA-GRU和GRU时间序列预测(改进的鲸鱼算法优化门控循环单元)

时序预测 | MATLAB实现IWOA-GRU和GRU时间序列预测(改进的鲸鱼算法优化门控循环单元) 目录 时序预测 | MATLAB实现IWOA-GRU和GRU时间序列预测(改进的鲸鱼算法优化门控循环单元)预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现IWOA-GRU和GRU时间序列预测…

详细全面讲解C++中重载、隐藏、覆盖的区别

文章目录 总结1、重载示例代码特点1. 模板函数和非模板函数重载2. 重载示例与调用规则示例代码调用规则解释3. 特殊情况与注意事项二义性问题 函数特化与重载的交互 2. 函数隐藏&#xff08;Function Hiding&#xff09;概念示例代码特点 3. 函数覆盖&#xff08;重写&#xff…

DAY15 神经网络的参数和变量

DAY15 神经网络的参数和变量 一、参数和变量 在神经网络中&#xff0c;参数和变量是两个关键概念&#xff0c;它们分别指代不同类型的数据和设置。 参数&#xff08;Parameters&#xff09; 定义&#xff1a;参数是指在训练过程中学习到的模型内部变量&#xff0c;这些变量…

git的rebase和merge的区别?

B分支从A分支拉出 1.git merge 处于A分支执行&#xff0c;git merge B分支:相当于将commit X、commit Y两次提交&#xff0c;作为了新的commit Z提交到了A分支上。能溯源它真正提交的信息。 2.git rebase 处于B分支&#xff0c;执行git rebase A分支&#xff0c;B分支那边复…

2、蓝牙打印机点灯-GPIO输出控制

1、硬件 1.1、看原理图 初始状态位高电平. 需要驱动PA1输出高低电平控制PA1. 1.2、看手册 a、系统架构图 GPIOA在APB2总线上。 b、RCC使能 GPIOA在第2位。 c、GPIO寄存器配置 端口&#xff1a;PA1 模式&#xff1a;通用推挽输出模式 -- 输出0、1即可 速度&#xff1a;5…

使用强化学习训练神经网络玩俄罗斯方块

一、说明 在 2024 年暑假假期期间&#xff0c;Tim学习并应用了Q-Learning &#xff08;一种强化学习形式&#xff09;来训练神经网络玩简化版的俄罗斯方块游戏。在本文中&#xff0c;我将详细介绍我是如何做到这一点的。我希望这对任何有兴趣将强化学习应用于新领域的人有所帮助…

基于springboot的网上商城购物系统

作者&#xff1a;学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等 文末获取“源码数据库万字文档PPT”&#xff0c;支持远程部署调试、运行安装。 目录 项目包含&#xff1a; 开发说明&#xff1a; 系统功能&#xff1a; 项目截图…

API架构风格的深度解析与选择策略:SOAP、REST、GraphQL与RPC

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

【网络协议】开放式最短路径优先协议OSPF详解(四)

前言 在本章的第一部分和第二部分中&#xff0c;我们探讨了OSPF的基本配置&#xff0c;并进一步学习了更多OSPF的概念&#xff0c;例如静态路由的重分发及其度量值。在第三部分中&#xff0c;我们讨论了多区域OSPF。在第四部分中&#xff0c;我们将关注OSPF与多访问网络&#…

上门按摩系统架构与功能分析

一、系统架构 服务端&#xff1a;Java&#xff08;最低JDK1.8&#xff0c;支持JDK11以及JDK17&#xff09;数据库&#xff1a;MySQL数据库&#xff08;标配5.7版本&#xff0c;支持MySQL8&#xff09;ORM框架&#xff1a;Mybatis&#xff08;集成通用tk-mapper&#xff0c;支持…

攻防世界 ics-07

点击之后发现有个项目管理能进&#xff0c;点进去&#xff0c;点击看到源码&#xff0c;如下三段 <?php session_start(); if (!isset($_GET[page])) { show_source(__FILE__); die(); } if (isset($_GET[page]) && $_GET[page] ! index.php) { include(flag.php);…

Spring Boot教程之四十九:Spring Boot – MongoRepository 示例

Spring Boot – MongoRepository 示例 Spring Boot 建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是…

测试ip端口-telnet开启与使用

前言 开发过程中我们总会要去测试ip通不通&#xff0c;或者ip下某个端口是否可以联通&#xff0c;为此我们可以使用telnet 命令来实现。 一、telnet 开启 可能有些人使用telnet报错&#xff0c;不是内部命令&#xff0c;可以如下开启&#xff1a; 1、打开控制面板&#xff…

SpringBoot3动态切换数据源

背景 随着公司业务战略的发展&#xff0c;相关的软件服务也逐步的向多元化转变&#xff0c;之前是单纯的拿项目&#xff0c;赚人工钱&#xff0c;现在开始向产品化\服务化转变。最近雷袭又接到一项新的挑战&#xff1a;了解SAAS模型&#xff0c;考虑怎么将公司的产品转换成多租…

爬虫学习记录

1.概念 通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程 通用爬虫:抓取的是一整张页面数据聚焦爬虫:抓取的是页面中的特定局部内容增量式爬虫:监测网站中数据更新的情况,只会抓取网站中最新更新出来的数据 robots.txt协议: 君子协议,网站后面添加robotx.txt…

通过 route 或 ip route 管理Linux主机路由

目录 一&#xff1a;route 使用说明1、查看路由信息2、删除指定路由3、增加指定路由 二&#xff1a;ip route 使用说明1、查看主机路由2、新增主机路由3、删除主机路由 通过route 或者ip route修改Linux主机路由后属于临时生效&#xff0c;系统重启后就恢复默认值了&#xff0c…

el-table表格合并某一列

需求&#xff1a;按照下图完成单元格合并&#xff0c;数据展示 可以看到科室列是需要合并的 并加背景色展示&#xff1b;具体代码如下&#xff1a; <el-tableref"tableA":data"tableDataList":header-cell-style"{ backgroundColor: #f2dcdb, col…

CSS Grid 布局全攻略:从基础到进阶

文章目录 一.Grid 是什么二.示例代码1. 基础使用 - 固定宽高2.百分百宽高3.重复设置-repeat4.单位-fr5.自适应6.间距定义其他 一.Grid 是什么 CSS 中 Grid 是一种强大的布局方式&#xff0c;它可以同时处理行和列 Grid 和Flex有一些类似&#xff0c;都是由父元素包裹子元素使用…

数据结构:包装类和泛型

目录 一、包装类 1、基本数据类型和对应的包装类 2、装箱和拆箱 3、自动装箱和自动拆箱 二、泛型 1、什么是泛型 2、泛型语法 3、泛型类 4、擦除机制 5、泛型的上界 6、泛型方法 三、通配符 1、什么是通配符 2、通配符上界 3、通配符下界 &#x1f4da…