基本概念
1.JS书写位置
行内式
html
<input type="button" value="点我一下" onclick="alert('haha')">
内嵌式:主要这样写
html
<script>
alert("haha");
</script>
外部式
html
<script src="hello.js"></script>
javascript
alert("hehe");
2.输入输出
javascript
// 弹出一个输入框
prompt("请输入您的姓名:");
// 弹出一个输出框
alert("hello");
// 向控制台输出日志
console.log("这是一条日志");
3.变量使用
let:变量
const:常量
数组和对象在JS中属于引⽤类型, 对其做添加、删除等操作, 并不改变其内存地址。
4.内置数据类型
number: 数字 . 不区分整数和小数 .
boolean: true 真 , false 假 .
string: 字符串类型 .
undefined: 只有唯一的值 undefined. 表示未定义的值 .
null: 只有唯一的值 null. 表示空值 .
5.引用数据类型
数组
创建数组
javascript
var arr = new Array();
var arr = [];
var arr2 = [1, 2, 'haha', false];
获取数组元素
javascript
var arr = ['小猪佩奇', '小猪乔治', '小羊苏西'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
arr[2] = '小猫凯迪';
console.log(arr);
// 如果下标超出范围读取元素, 则结果为 undefined
console.log(arr[3]); // undefined
console.log(arr[-1]); // undefined
新增数组元素
javascript
// 1. 通过修改 length 新增
let arr = [9, 5, 2, 7];
arr.length = 6;//相当于在末尾新增元素. 新增的元素默认值为 undefined
console.log(arr);
console.log(arr[4], arr[5]);
// 2. 通过下标新增
let arr = [];
arr[2] = 10; // 如果下标超出范围赋值元素, 则会给指定位置插入新元素
// 此时这个数组的 [0] 和 [1] 都是 undefined
console.log(arr)
// 3.使用 push 进行追加元素
let newArr = [];
newArr.push(1);
删除数组元素
javascript
// 使用 splice 方法删除元素
var arr = [9, 5, 2, 7];
// 第一个参数表示从下表为 2 的位置开始删除. 第二个参数表示要删除的元素个数是 1 个
arr.splice(2, 1);
console.log(arr);
// 结果
[9, 5, 7]
对象
创建对象
使用 字面量 创建对象
javascript
let a = {}; // 使用 { } 创建对象
let student = {
name: '蔡徐坤',
height: 175,
weight: 170,
sayHello: function() {
console.log("hello");
}
};
// 使用对象的属性和方法
// 1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的"
console.log(student.name);
// 2. 使用 [ ] 访问属性, 此时属性需要加上引号
console.log(student['height']);
// 3. 调用方法, 别忘记加上 ()
student.sayHello();
使用 new Onject 创建对象
javascript
let student = new Object(); // 和创建数组类似
student.name = "蔡徐坤";
student.height = 175;
student['weight'] = 170;
student.sayHello = function () {
console.log("hello");
}
console.log(student.name);
console.log(student['weight']);
student.sayHello();
// 使用 { } 创建的对象也可以随时使用 student.name = "蔡徐坤"; 这样的方式来新增属性.
使用 构造函数 创建对象
javascript
function Cat(name, type, sound) {
this.name = name;
this.type = type;
this.miao = function () {
console.log(sound); // 别忘了作用域的链式访问规则
}
}
var mimi = new Cat('咪咪', '中华田园喵', '喵');
var xiaohei = new Cat('小黑', '波斯喵', '猫呜');
var ciqiu = new Cat('刺球', '金渐层', '咕噜噜');
console.log(mimi);
mimi.miao();
简写
属性的简写
javascript
// 当属性名和属性值的名字⼀样时, 并且配合变量时,可以简写
let min = 1
let max = 99
// 以前的写法(不简写)
const obj = {
min: min,
max: max
}
// 现在的写法
const obj = {
min,
max
}
方法的简写
javascript
const obj = {
// 不简写
fn: function() {
}
}
// 等同于
const obj = {
// 简写: 连同 :和function ⼀起省略
fn() {
}
}
基础DOM
1.获取元素
2.事件
3.操作元素
4.操作节点
一.模版字符串
使用反引号声明,好处:可以任意换行和可嵌入表达式
javascript// 1. 就是可以在字符串里面换行 // 2. 可嵌入表达式 // 避免了繁琐的 加号 做字符串拼接; 嵌⼊的语法 ${表达式} let name = 'Bit' let age = 9 let str = `My name is ${name}, I am ${age} years old, ${age >= 18 ? '已成年':'未成年'}`
二.解构赋值-让数组和对象赋值更方便给变量赋值
数组解构
javascript
const arr = [11, 22, 33]
// eg1: 把 arr 中的3个值分别赋值给变量 a, b, c
// 以前的写法
let a = arr[0]
let b = arr[1]
let c = arr[2]
// 现在的写法
let [a, b, c] = arr
// eg2: 把 arr 中的后两个值赋值给变量 b,c
let [,b,c] = arr
// eg3: 把 arr 中的第1个值赋值给变量 a, 剩余的全部给到变量 rest
let [a, ...rest] = arr
对象解构
javascript
const obj = {
name: '冉汉梦',
age: 18,
address: '武昌首义学院'
}
// eg1: 把 obj 中的3个属性值分别赋值给变量 name, age, address
// 以前的写法
const name = obj.name
const age = obj.age
const address = obj.address
// 现在的写法
const { name, age, address } = obj
// eg2: 把 obj 的 age, address 属性值赋值给 age, address
const { age, address } = obj
// eg3: 把 obj 的 name 属性值赋值给变量 name, 剩余的全部给到变量 rest
const { name, ...rest } = obj
// eg4: 把 obj 的 name 属性值赋值给变量 uname
const { name: uname } = obj
三.箭头函数
作用:可⽤于普通函数的声明, 也多⽤于回调函数传参
javascript// 基本使用 const add = (x, y) => { return x + y } // 参数只有⼀个可以省略⼩括号、函数体⼀句话可以省略⼤括号 const log = arg => console.log(arg) // 当省略了⼤括号时, 函数⾃带 return const add = (x, y) => x + y // 当函数体直接返回⼀个对象, 如果简写, 需要给对象加⼀对⼩括号 const state = () => ({ token: 'xxxx', userInfo: { name: 'admin', id: 1 } })
四.扩展运算符
复制数组或对象-这个类似深拷贝
javascript
const arr1 = [11, 22, 33]
// 赋值
const arr2 = arr1
arr2.push(44)
console.log(arr1)// 受影响了
// ... 是展开一个数组,所以我们要把数据复制到一个数组,我们还需要添加[ ]
// 正确的做法, 把 arr1 复制⼀份给到 arr2
const arr2 = [...arr1]
const obj1 = {
id: 10001,
name: 'Bit',
age: 9
}
// 赋值
const obj2 = obj1
obj2.age = 10
console.log(obj1)// 受影响了
// 正确的做法, 把 obj1 复制⼀份给到 obj2
// 展开运算符号不能展开一个对象,所以这里必须要添加{ },意思是不能直接写 ...obj1
const obj2 = {...obj1}
合并数组或对象
javascript
const arr1 = [1,2,3]
const arr2 = [4,5,6]
// 把 arr1 和 arr2 合并起来给到 arr
const arr = [...arr1, ...arr2]
const obj1 = {
name: 'Jack',
height: 176
}
const obj2 = {
height: 180,
age: 18
}
// 把 obj1 和 obj2 合并起来给到 obj
// 注意: 同名属性会覆盖
const obj = {
...obj1,
...obj2
}
五.序列化和反序列化
javascript
// 对象
const json = {
id: 10001,
name: '冉汉梦',
age: 9
};
// 序列化:将对象转为 JSON 字符串
const jsonStr = JSON.stringify(json);
// json 字符串
const jsonStr2 = '{"id": 10001, "name": "Bit", "age": 9}';
// 反序列化:将 JSON 字符串转为对象
const parsedJson = JSON.parse(jsonStr);
六.Web存储
七.Promise+Aysnc/Await
简单介绍Promise
Promise是⼀个类, ⽤来包装异步操作, 根据异步操作的结果, 是成功还是失败, 进⽽决定Promise是成功还是失败;Promise⽀持链式调⽤, 从⽽消除回调地狱
promise有三种状态: Pending : 进⾏中、 Fulfilled : 成功、 Rejected : 失败
Promise基本使用
javascript
const p = new Promise((resolve, reject) => {
// 这里编写异步代码:比如定时器、ajax请求等
setTimeout(() => {
// 2秒后, Promise标记为成功
resolve('ok')
reject('error') // 如果成功和失败的函数都写了,只会调用写的第一个,因为promise的状态不可变
}, 2000)
})
p.then((msg) => {
// 成功回调
console.log(msg)// ok
}, (err) => {
// 失败回调
console.log(err)// error
})
使用案例:延迟2秒之后输出1, 完了之后延迟1秒输出2, 完了之后延迟1秒输出3
如果直接写setTimeout调用,这样嵌套太多不方便浏览代码
javascript// 封装延迟函数 function delay(duration, n) { return new Promise((resolve) => { setTimeout(() => { resolve(n) }, duration) }) } // 链式调用消除回调地狱 delay(2000, 1) .then(n1 => { console.log(n1) return delay(1000, 2) }).then(n2 => { console.log(n2) return delay(1000, 3) }).then(n3 => { console.log(n3) })上述代码虽然消除了回调地狱、但链式调⽤过⻓、也不利于阅读,为了继续优化、Aysnc+Await就应运⽽⽣了
Promise.all静态方法
javascript
const p = Promise.all([Promise对象, Promise对象, ...])
p.then(result => {
// result结果:[Promise对象成功结果, Promise对象成功结果, ...]
}).catch(error => {
// 第一个失败的Promise对象,抛出的异常
})
Aysnc+Await基本使用
async函数内, 当前await执⾏结束了,代码才会继续往后执⾏
javascript// 封装延迟函数 function delay(duration, n) { return new Promise((resolve) => { setTimeout(() => { resolve(n) }, duration) }) } // 语法 async function log() { // 1、在Promise实例前添加 await 关键字, 那么await的返回值就是当前Promise的resolve参数 // 2、await所在的函数必须被async修饰 // 3、async函数内, 当前await执⾏结束了,代码才会继续往后执⾏(同步的⽅式执⾏) const n1 = await delay(2000, 1) console.log(n1) // resolve的参数 } log()
八.模块化
使用commonjs标准导入导出(es6之前)


使用ECMAScript标准-默认导入和导出(es6)
| 特性 | 默认导出(Default Export) | 按需导出(Named Export) |
| 导出数量 | 一个模块只能有 1 个默认导出 | 一个模块可以有 多个按需导出 |
| 导出语法 | 使用 export default 成员 | 使用 export { 成员1, 成员2, ... } 或直接在成员前加 export |
| 导入语法 | import 自定义名称 from '模块路径'(无需 {}) | import { 成员名1, 成员名2, ... } from '模块路径'(必须用 {} 且名称需匹配) |
| 成员名称 | 导出时可以匿名(如 export default function() {}),导入时可自定义名称 |
导出时必须有明确名称,导入时必须使用相同名称(可通过 as 重命名) |
|---|


使用ECMAScriot标准-命名导出和导入(es6)


总结

九.深入理解js
事件循环
- 什么是事件循环?
- 执行代码和收集异步任务,在调用栈空闲时,反复调用任务队列里回调函数执行机制
- 为什么有事件循环?
- JavaScript 是单线程的,为了不阻塞 JS 引擎,设计执行代码的模型
- JavaScript 内代码如何执行?
- 执行同步代码,遇到异步代码交给宿主浏览器环境执行
- 异步有了结果后,把回调函数放入任务队列排队
- 当调用栈空闲后,反复调用任务队列里的回调函数
宏任务和微任务
- 什么是宏任务?
- 浏览器执行的异步代码
- 例如:JS 执行脚本事件,setTimeout/setInterval,AJAX 请求完成事件,用户交互事件等
- 什么是微任务?
- JS 引擎执行的异步代码
- 例如:Promise 对象.then () 的回调
- JavaScript 内代码如何执行?
- 执行第一个 script 脚本事件宏任务,里面同步代码
- 遇到宏任务 / 微任务交给宿主环境,有结果回调函数进入对应队列
- 当执行栈空闲时,清空微任务队列,再执行下一个宏任务,从 1 再来

十.ES2020
可选链操作符
javascript
// 如果 error.response 不存在,直接返回 undefined,不报错
const msg = error.response?.data?.message;
数组的重要方法
对象的重要方法
字符串
react必备语法
对象的计算属性名
通过这种语法,你可以在对象字面量中使用表达式(如变量、函数调用等)来动态生成属性名,形式为
{ [表达式]: 值 },让对象属性的定义更加灵活。