
🚀 欢迎来到我的CSDN博客:Optimistic _ chen
✨ 一名热爱技术与分享的全栈开发者,在这里记录成长,专注分享编程技术与实战经验,助力你的技术成长之路,与你共同进步!
🚀我的专栏推荐:
| 专栏 | 内容特色 | 适合人群 |
|---|---|---|
| 🔥C语言从入门到精通 | 系统讲解基础语法、指针、内存管理、项目实战 | 零基础新手、考研党、复习 |
| 🔥Java基础语法 | 系统解释了基础语法、类与对象、继承 | Java初学者 |
| 🔥Java核心技术 | 面向对象、集合框架、多线程、网络编程、新特性解析 | 有一定语法基础的开发者 |
| 🔥Java EE 进阶实战 | Servlet、JSP、SpringBoot、MyBatis、项目案例拆解 | 想快速入门Java Web开发的同学 |
| 🔥Java数据结构与算法 | 图解数据结构、LeetCode刷题解析、大厂面试算法题 | 面试备战、算法爱好者、计算机专业学生 |
| 🔥Redis系列 | 从数据类型到核心特性解析 | 项目必备 |
🚀我的承诺:
✅ 文章配套代码:每篇技术文章都提供完整的可运行代码示例
✅ 持续更新:专栏内容定期更新,紧跟技术趋势
✅ 答疑交流:欢迎在文章评论区留言讨论,我会及时回复(支持互粉)
🚀 关注我,解锁更多技术干货!
⏳ 每天进步一点点,未来惊艳所有人!✍️ 持续更新中,记得⭐收藏关注⭐不迷路 ✨
📌 标签:#技术博客 #编程学习 #Java #C语言 #算法 #程序员
文章目录
- 前言
- 变量和常量
- 模板字符串
- 对象
- 解构赋值(重点)
- 箭头函数(重点)
- 数组方法
-
- [push()尾插 和 unshift()头插](#push()尾插 和 unshift()头插)
- [pop()尾删 和 shift()头删](#pop()尾删 和 shift()头删)
- 任意位置删除或添加splice()
- 包含includes()
- 遍历forEach()
- 检测每一个every()
- 汇总reduce()
- 对象方法:keys()
- Web存储
- 消除回调地狱
- 完结撒花!🎉
前言
作为一名后端开发者,掌握前端技能已成为我们的加分项。具备前端能力不仅能带来更多关注,还能创造更多职业机会。
"刚打开Vue3文档看了10分钟就放弃了?"
"按文档敲代码却遇到一堆报错?"
如果你正面临这些困扰,请放心------问题不在于你的能力,而是你可能忽略了一些"隐形门槛"。
许多初学者在学习Vue3时容易陷入一个误区:直接上手框架,却忽略了基础知识。
这就好比:
- 还没学会走路就想跑步
- 单词都没掌握就想写文章
- 不了解HTML标签就想做网页
虽然Vue3语法简洁,但它建立在JavaScript核心概念之上。如果这些基础不扎实,阅读文档就像看天书一样困难。但是,来跟紧我的博客思路,你就会恍然开朗,柳暗花明又一村。
变量和常量
如果有语言基础,这两个东西应该很熟悉。顾名思义:
变量:可以变化的,可以对其多次赋值
javascript
let name='xiaowang'
name='xiaozhao'
常量:不可变的,不可对其二次赋值
javascript
const PI=3.14
const user={
name:'zhangsan',
age:55
}
那么有人或许会有疑问?const声明的数组或对象可以对其进行一系列操作吗?
这涉及到const的真正含义,简单来说:const声明禁止的是"变量的重新赋值,而不是变量内容的修改"
我们知道数据的基本类型是直接存储在栈内存中,变量名直接指向具体的值;引用类型存储在堆内存中,变量名只是一个指针,指向堆内存中存放数据的内存地址。
当你声明变量时,const 锁住的是栈内存里的地址。但是引用类型需要修改引用的地址。

总结:
- 引用类型:const 保证的是"指向该地址的绑定不能改变",而不是"该地址指向的内容不可改变"。
- 基本类型:由于赋值即意味着改变值本身,也就是改变引用,所以 const 声明的字面量不能修改。
模板字符串
模板字符串:是ES6引入的一种新的字符串语法,使用反引号 ` 代替传统的引号声明;而传统字符串用一对单引号或双引号声明
声明方式:
javascript
//传统字符串
const str1="普通字符串"
const str2='普通字符串'
//模板字符串
const str3=`模板字符串`
优势:
- 字符串插值,支持嵌入任何使用表达式
${},避免繁琐的加号
javascript
const name='zhangsan'
const age=18
//传统方式
const result1 = '我叫' + name + ',今年' + age + '岁'
//模板字符串
const result2=`我叫${name},今年${age}岁`
- 任意换行
javascript
let htmlStr = '<div class="hot-goods-box"><h1>热门商品</h1><p>卖爆了卖爆了卖爆了</p></div>'
let htmlStr =
`<div class="hot-goods-box">
<h1>热门商品</h1>
<p>卖爆了卖爆了卖爆了</p>
</div>`
对象
对象我们应该是特别熟悉的,它是一个个个体,也是一堆属性和方法的集合
我们要从对象中获取值,有两种方式点取值和中括号取值。
- 点取值:.属性名
javascript
const user={
name: 'zhangsna',
age: 15
}
console.log(user.name)
console.log(user.age)
//或者
console.log(user['name'])//name加引号 - javascript会直接用name这个字符串作为属性名
console.log(user['age'])//如果age不加引号 - javascript会直接找一个变量名为age的变量
- 中括号取值:[ 表达式 ]
javascript
const user={
name: 'zhangsna',
age: 15
}
let x='name'
let y='age'
console.log(user[x])
console.log(user[y])
注意:当属性名是变量的时候,只能用中括号取值,否则既可以用点取值,也可以用中括号取值
对象的简写
当属性名和变量名一样时,可以简写:
- 属性简写
javascript
// 传统写法
const name = '张三'
const age = 25
const user = {
name: name,
age: age,
gender: '男'
}
// ES6 简写
const user = {
name, // 相当于 name: name
age, // 相当于 age: age
gender: '男'
}
console.log(user) // {name: '张三', age: 25, gender: '男'}
- 方法简写
javascript
// 传统写法
const obj = {
sayHello: function() {
console.log('Hello')
},
add: function(a, b) {
return a + b
}
}
// ES6 简写
const obj = {
sayHello() {
console.log('Hello')
},
add(a, b) {
return a + b
}
}
// 调用
obj.sayHello() // Hello
console.log(obj.add(1, 2)) // 3
解构赋值(重点)
针对数组或者对象进行解构,目的是为了取值更加便捷。
- 数组解构
javascript
const arr=[1,2,3]
//传统写法
let a=arr[0]
let b=arr[1]
let c=arr[2]
//解构代码
let [a,b,c]=arr
let [,b,c]=arr//把 arr 中的后两个值赋值给变量b,c
- 对象解构
javascript
const obj{
name: 'zhangsan',
age: 18,
address: '中国北京'
}
//解构代码
const {name,age,address}=obj
箭头函数(重点)
首先,我们需要观察普通函数和箭头函数的区别:
javascript
//普通函数
function add(a,b){
return a+b
}
//箭头函数
const add = (a,b)=>{
return a+b
}
//简写:函数体只有⼀句话可以省略⼤括号,函数自带return
const add=(a,b)=> a+b
//简写:单个参数可以省略括号
const fun = x => x*2
箭头函数的语法const fun = () => { return ...} ,那么它有哪些显著特点呢?
- 箭头函数不会创建自己的
this,只会从自己的作用域链的上一层继承this
javascript
// 示例2:深入理解"定义时"
class Timer {
constructor() {
this.seconds = 0
this.name = 'Timer'
}
// 使用传统函数
startTraditional() {
console.log('startTraditional 的 this:', this.name) // 'Timer'
setInterval(function() {
// 这里的 this 是谁?取决于如何调用
// 在全局上下文中调用,所以 this 是 window(或 undefined)
console.log('传统函数内部:', this.name) // undefined
this.seconds++ // 错误:无法增加 seconds
}, 1000)
}
// 使用箭头函数
startArrow() {
console.log('startArrow 的 this:', this.name) // 'Timer'
setInterval(() => {
// 这个箭头函数在 startArrow 内部定义
// 所以它捕获了 startArrow 的 this(即 Timer 实例)
console.log('箭头函数内部:', this.name) // 'Timer'
this.seconds++ // 正确:增加 Timer 实例的 seconds
}, 1000)
}
回调函数
回调函数是作为参数传递给另一个函数的函数,它会在特定事件发生后被调用。
javascript
//定时器回调
setTimeout(
function(){console.log('1秒后执行')},//参数1:回调函数
1000 //参数2:延迟时间
)
setTimeout 就像是一个调度员,它接收你的任务(函数),然后安排在未来某个时间执行,而不是立即执行或包装执行。
把箭头函数作为回调函数:
javascript
// 函数可以作为参数传递
setTimeout(
() => { console.log('函数作为参数传递') }, // 函数作为第一个参数
1000
)
// 这体现了 JavaScript 中函数可以像变量一样被传递
const myFunction = () => console.log('函数赋值给变量') //箭头函数作为变量
setTimeout(myFunction, 2000) // 函数作为参数传递
这是现代 JavaScript 异步编程的基础模式,体现了 JavaScript 的非阻塞特性
数组方法
数组是最常见的数据集合,也是js的重要数据结构,它的每一个方法我们都会用到,所以难点不在学习,而是记忆,需要在恰当的时候记起来使用。
push()尾插 和 unshift()头插
javascript
const arr=[1,2,3]
//尾插
const len=arr.push(4)
console.log(len) //4
//头插
const x=arr.unshift(0)
console.log(x) // 5
注意:两者都返回的是新数组长度
pop()尾删 和 shift()头删
javascript
const arr=[1,2,3]
//尾删
const last=arr.pop()
console.log(last) //3
//头删
const first=arr.shift()
console.log(first) // 1
注意:两者都返回被删除的元素
任意位置删除或添加splice()
javascript
const arr = [11, 22, 33, 44]
// arr.splice(startIndex:number, delCount:number, ...addItem)
// 删除的起始下标, 要删除的个数, ...可以传入0个或多个要添加的元素
// 删除22
const temp = arr.splice(1, 1)
console.log(temp)// [22]
console.log(arr)// [11, 33, 44]
// 33后⾯添加55
arr.splice(2, 0, 55)
console.log(arr)// [11, 22, 33, 55, 44]
注意:splice() 方法返回的是被删除的元素组成的数组!
包含includes()
javascript
const arr = [11, 22, 33, 44]
console.log(arr.includes(33))// true
console.log(arr.includes(55))// false
注意:includes() 方法返回的是布尔值,如果包含传入参数则返回true;否则返回false
遍历forEach()
javascript
const arr=[1,2,3,4]
arr.forEach((item,index,arr)=>{
//item:每次遍历的元素
//index:元素下标
//arr:数组本身
})
forEach 接收一个回调函数作为参数,这个回调函数会在数组的每个元素上被调用.
检测每一个every()
javascript
const arr=[1,2,3,4]
//语法
arr.every((item,index,arr)=>{
//如果返回true,说明当前元素满足条件,继续下一次检测
//若都满足条件,则最终返回true
//如果返回false,说明当前元素不满足条件,
//立即停止检测,最终返回fasle
return 布尔值})
//判断arr中元素是否都是奇数
const bool=arr.every((item)=>{
console.log(item)
return item%2===1
})
注意:JavaScript中的函数参数是按需索取,只传入需要的参数即可;===是为了严格比较,避免JavaScript 自动类型转换带来的意外结果
汇总reduce()
javascript
//语法
// prev:上一次回调的返回值(累加器)
// item:当前遍历的元素
const result=arr.reduce(
(prev,item,index,array)=>{return 结果},
初始值
)
//对arr求和
const arr=[1,3,5,7]
//const sum=arr.reduce((prev,item)=>{return prev+item},0)
// prev: 0, item: 1, 返回: 1 (第1次:0 + 1 = 1)
// prev: 1, item: 3, 返回: 4 (第2次:1 + 3 = 4)
// prev: 4, item: 5, 返回: 9 (第3次:4 + 5 = 9)
// prev: 9, item: 7, 返回: 16 (第4次:9 + 7 = 16)
const sum=arr.reduce((prev,item) => prev+item,0)
对象方法:keys()
javascript
const obj = {
id: 1,
name: 'zhangsan',
age: 19,
address: '中国北京'
// 获取对象键的数组
const keys = Object.keys(obj)
console.log(keys)// ['id', 'name', 'age']
Object.keys()拿到的是键的数组,可以对数组做很多处理在进⾏遍历对象
Web存储
Web Storage包含两种储存机制:
sessionStorage该存储区域在页面会话期间可用(浏览器处于打开状态,包括⻚⾯重新加载和恢复)localStorage即使关闭浏览器并重新打开也仍然存在
注意:sessionStorage仅为会话存储数据,这意味着数据将⼀直存储到浏览器(或选项卡)关闭,数据永远不会被传输到服务器。 localStorage存储的数据没有过期⽇期,只能通过JavaScript、清除浏览器缓存或本地存储的数据来清除
我们以localStorage为例子学习存取和删除
javascript
//存
//语法
localStorage.setItem(key:string, value:string)
localStorage.setItem('name', 'lisi')
javascript
//取
//语法
localStorage.getItem(key:string)
localStorage.getItem('name')
javascript
//删除
//语法
localStorage.removeItem(key:string)
localStorage.removeItem('name')
注意:存储对象和数组需要进行序列化和反序列化
javascript
const obj = {
id: 1,
name: 'lisi',
age: 9
}
// 存: 序列化
localStorage.setItem('lisi', JSON.stringify(obj))
// 取: 反序列化
const local = JSON.parse(localStorage.getItem('lisi))
消除回调地狱
多个回调函数嵌套,代码的可读性非常差,就会出现所谓的回调地狱,为了解决这个问题,Promise就出现了。
我们前面提到回调函数实现了异步编程,Promise是一个类,是包装异步操作, 根据异步操作的结果来决定Promise是成功还是失败;Promise支持链式调用,从而消除回调地狱。
Promise的三种状态分别是:
javascript
Pending: 进行中
Fulfilled: 成功
Rejected:失败
Promise状态要求及其严格,只能由Pending -> Fulfilled或者Pening -> Rejected,并且一旦确定状态,就不会更改。
javascript
//Promise基本工作原理和状态不可逆性
const p=new Promise((resolve,reject)=>{
//编写异步操作
setTimeout(()=>{
//2秒后,Promise标记为成功
resolve('ok')
reject('error')
},2000)
})
p.then((msg)=>{
//成功回调
console.log(msg) //ok
},(err)=>{
//失败回调
console.log(err)
})
使用Promise消除回调地狱
javascript
//封装延迟函数
function delay(duration ,n){
return new Promise(()=>{
setTimeout(()=>{
resolve(n) // 将 n 作为成功值传递
},duration) // 等待duration毫秒后,调用resolve()
})
}
//链式调用
delay(2000,1).then(n1=>{
console.log(n1) //输出1
return delay(1000,2) //返回新的Promise,等待1秒
}).then(n2=>{
console.log(n2) //输出2
return delay(1000,3) //返回新的Promise,等待1秒
}).then(n3=>{
console.log(n3) //输出3
})
虽然利用Promise消除了回调地狱,但是链式调用太长,代码太过冗余,为了继续优化,Aysnc+Await就应运而生了。
javascript
//封装延迟函数
function delay(duration ,n){
return new Promise(()=>{
setTimeout(()=>{
resolve(n) // 将 n 作为成功值传递
},duration) // 等待duration毫秒后,调用resolve()
})
}
async function log(){
const n1=await delay(2000,1)
console.log(n1)
const n2=await delay(1000,2)
console.log(n2)
const n3=await delay(1000,3)
console.log(n3)
}
log()
在Promise实例之前添加await关键字,那么await返回值就是当前Promise的resolve参数,同时,wwait所在函数必须被async修饰,async函数内当前await执⾏结束了,代码才会继续往后执⾏(同步的⽅式执⾏)
完结撒花!🎉

如果这篇博客对你有帮助,不妨点个赞支持一下吧!👍
你的鼓励是我创作的最大动力~
✨ 想获取更多干货? 欢迎关注我的专栏 → optimistic_chen
📌 收藏本文,下次需要时不迷路!
我们下期再见!💫 持续更新中......
悄悄说:点击主页有更多精彩内容哦~ 😊
