JS学习笔记

webAPIs
属性选择器
1 | <a class="test" id="idtest" data-state="selected" name="name" </a> |
classList
1 | //添加类 |
offsetWidth
1 | //只读元素 获取宽高,元素的内容+padding+border |
clientWidth
1 | //读写元素 |
scrollTop
1 | //获取滚动距离 |
日期对象
1 | const date = new Date() |
节点
1 | //父节点 |
移动端
1 | const div = document.querySelector('div') |
轮播图插件:swiper
倒计时
1 | //1s后执行,只会执行一次 |
定时器
1 | //每隔1s执行 |
location对象
1 | // 1. href 经常用href 利用js的方法去跳转页面 |
检测浏览器信息
1 | // 检测 userAgent(浏览器信息) |
history:浏览器历史
1 | const back = document.querySelector('button:first-child') |
### ocalStorage:本地存储(除非手动删除,否则永远储存)
1 | // 1. 要存储一个名字 'uname', 'pink老师' |
数组map方法
1 | const arr = ['red', 'blue', 'green'] |
数组join方法
1 | const arr = ['red', 'blue', 'green'] |
正则表达式
1 | const str = '我们在学习前端,希望学习前端能高薪毕业' |
e
1 | const pane = document.querySelectorAll('.tab-pane') |
获取元素位置
1 | // e.pageX e.pageY 鼠标位置 |
ES6+
闭包
外部可以访问使用 函数内部的变量
1 | // 闭包形式 统计函数调用的次数 |
变量提升
- 把所有var声明的变量提升到 当前作用域的最前面
- 只提升声明, 不提升赋值
函数提升
- 会把所有函数声明提升到当前作用域的最前面
- 只提升函数声明,不提升函数调用
1 | fn() |
- 函数表达式 必须先声明和赋值, 后调用 否则 报错
1 | fun() |
动态数组
1 | //伪数组 |
剩余参数
1 | //真数组 |
展开运算符
1 | const arr1 = [1, 2, 3] |
箭头函数
基本语法
1
2
3
4
5
6
7const fn = () => {
console.log(123)
}
fn()
//等同于 const fn = function () {
// console.log(123)
// }只有一个参数时
1
2
3
4// 只有一个形参的时候,可以省略小括号
const fn = x => {
console.log(x)
}只有一行代码的
1
2
3
4
5// 只有一行代码的时候,我们可以省略大括号
const fn = x => console.log(x)
//只有一行代码的时候,可以省略return
const fn1 = (x,y) => x + y
console.log(fn1(1))箭头函数可以直接返回一个对象(对象需要加“()”)
1
2const fn = (uname) => ({ uname: uname })
console.log(fn('刘德华'))没有arguments 动态参数,但是剩余参数
1
2
3
4
5
6
7
8
9const getSum = (...arr) => {
let sum = 0
for (let i = 0; i < arr.length; i++) {
sum += arr[i]
}
return sum
}
const result = getSum(2, 3, 4)
console.log(result) // 9箭头函数没有this,是上一层作用域的this 指向
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//以前this的指向: 谁调用的这个函数,this 就指向谁
console.log(this) // window
// 普通函数
function fn() {
console.log(this) // window
}
window.fn()
// 对象方法里面的this
const obj = {
name: 'andy',
sayHi: function () {
console.log(this) // obj
}
}
obj.sayHi()
// 2. 箭头函数的this 是上一层作用域的this 指向
const fn = () => {
console.log(this) // window
}
fn()
// 对象方法箭头函数 this
const obj = {
uname: 'pink老师',
sayHi: () => {
console.log(this) // this 指向谁? window
}
}
obj.sayHi()
数组解构
1 | // const arr = [100, 60, 80] |
注意需要加” ; “,用来示意语句结束
1 | // 1. 立即执行函数要加 |
对象解构
解构基本语法
1
2
3
4
5
6
7
8const { uname, age } = {age: 18, uname: 'pink老师' }
// 等价于 const uname = obj.uname
// 要求属性名和变量名必须一直才可以
// 对象解构的变量名 可以重新改名 旧变量名: 新变量名
const { uname: username, age } = { uname: 'pink老师', age: 18 }
console.log(username)
console.log(age)解构数组对象
1
2
3
4
5
6
7
8
9const pig = [
{
uname: '佩奇',
age: 6
}
]
const [{ uname, age }] = pig
console.log(uname)
console.log(age)多级对象解构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//普通对象
const pig = {
name: '佩奇',
family: {
mother: '猪妈妈',
father: '猪爸爸',
sister: '乔治'
},
age: 6
}
// 多级对象解构
const { name, family: { mother, father, sister } } = pig
console.log(name)
console.log(mother)
console.log(father)
console.log(sister)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//数组对象
const person = [
{
name: '佩奇',
family: {
mother: '猪妈妈',
father: '猪爸爸',
sister: '乔治'
},
age: 6
}
]
const [{ name, family: { mother, father, sister } }] = person
console.log(name)
console.log(mother)
console.log(father)
console.log(sister)还可以这样使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// 1. 这是后台传递过来的数据
const msg = {
"code": 200,
"msg": "获取新闻列表成功",
"data": [
{
"id": 1,
"title": "5G商用自己,三大运用商收入下降",
"count": 58
},
{
"id": 2,
"title": "国际媒体头条速览",
"count": 56
},
{
"id": 3,
"title": "乌克兰和俄罗斯持续冲突",
"count": 1669
},
]
}
// 需求, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData
function render({ data: myData }) {
// 要求将 获取过来的 data数据 更名为 myData
// 内部处理
console.log(myData)
}
render(msg)
forEach
1 | // forEach 就是遍历 加强版的for循环 适合于遍历数组对象 |
filter
1 | const arr = [10, 20, 30] |
构造函数
- 创建结构相同但值不同的对象
- 构造函数创建的实例对象彼此独立互不影响
- 构造函数的属性被称为静态属性,构造函数的方法被称为静态方法(总称静态成员)
1 | functon Pig(uname,age){ |
js 底层完成, 把简单数据类型包装为了引用数据类型
1 | const str = 'pink' |
内置构造函数
Object
获得所有的属性名 Object.keys()
1
2const o = { uname: 'pink', age: 18 }
console.log(Object.keys(o)) //返回数组['uname', 'age']获得所有的属性值 Object.values() ,返回的是数组
1
2const o = { uname: 'pink', age: 18 }
console.log(Object.values(o)) // ['pink', 18]对象的拷贝
1
2
3
4
5
6const o = { uname: 'pink', age: 18 }
// const oo = {}
// Object.assign(oo, o)
// console.log(oo)
Object.assign(o, { gender: '女' })
console.log(o)
Array
实例方法:forEach(不返回数组,用于查找遍历数组元素),filter(返回筛选满足条件的新数组),map(返回处理之后的新数组),reduce(返回累计处理的结果,经常用于求和)
1 | // arr.reduce(function(累计值, 当前元素){}, 起始值) |
find和every
1 | // 1.find 查找 返回这个对象 |
实例方法简记

静态方法:Array.form(),把伪数组转换为真数组
1 | // Array.from(lis) 把伪数组转换为真数组 |
String
实例方法
split 把字符串 转换为 数组
1
2
3
4
5
6
7//1. split 把字符串 转换为 数组 和 join() 相反
const str = 'pink,red'
const arr = str.split(',')
console.log(arr)
const str1 = '2022-4-8'
const arr1 = str1.split('-')
console.log(arr1)字符串的截取 substring
1
2
3
4
5// 字符串的截取 substring(开始的索引号[, 结束的索引号])
// 如果省略 结束的索引号,默认取到最后
// 结束的索引号不包含想要截取的部分 左闭右开
const str = '今天又要做核酸了'
console.log(str.substring(5, 7))// 核酸startsWith
1
2
3// startsWith 判断是不是以某个字符开头
const str = 'pink老师上课中'
console.log(str.startsWith('pink'))//trueincludes
1
2
3// includes 判断某个字符是不是包含在一个字符串里面 区分大小写
const str = '我是pink老师'
console.log(str.includes('pink')) // true转字符串
1
2
3const num = 10
console.log(String(num))
console.log(num.toString())
Number
toFixed
1 | // toFixed 方法可以让数字指定保留的小数位数 四舍五入 |
两种编程思想
面向过程
分析出解决问题需要的步骤,然后用函数把这些步骤一步一步实现,按照步骤解决问题.比如c语言
面向对象
把事务分解为一个个对象,然后对象之间分工合作,以对象功能来划分问题.比如java
特点: 封装性 继承性 多态性
原型对象
- JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象
- 这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存
- 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。
- 构造函数和原型对象中的this 都指向 实例化的对象
1 | let that |
公共方法挂载到原型身上
1 | // 自己定义 数组扩展方法 求和 和 最大值 |
constructor
指向创造这个原型对象的 构造函数
类似继承覆盖?
1 | function Star() { |
对象原型
对象都会有一个属性__proto__指向构造函数的prototype原型对象 ,之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在.__proto__也有constructor属性指向创造这个对象的构造函数
__proto__不是js标准属性,只读
1 | function Star() { |
原型继承
抽取公共的方法和属性
1 | // 继续抽取 公共的部分放到原型上 |
原型链
基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链.

① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)
③ 如果还没有就查找原型对象的原型(Object的原型对象)
④ 依此类推一直找到 Object 为止(null)
⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线
⑥ 可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
1 | // function Objetc() {} |
JavaScript 中对象的工作机制:当访问对象的属性或方法时,先在当前实例对象是查找,然后再去原型对象查找,并且原型对象被所有实例共享。
拷贝
浅拷贝:对基本数据类型进行值传递,对引用数据类型,使用其引用地址,不拷贝其内容,此为浅拷贝
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
浅拷贝
1 | const obj = { |
深拷贝
循环递归方法
1 | const obj = { |
lodash方式
1 | <script src="./lodash.min.js"></script> |
JSON 方法
1 | const obj = { |
异常处理
throw
1 | function fn(x, y) { |
try catch
1 | function fn() { |
this
普通函数中
1 | // 普通函数: 谁调用我,this就指向谁 |
箭头函数
箭头函数中并不存在this,箭头函数中this默认绑定外层(最近作用域)this的值.
改变this指向
call
1 | const obj = { |
apply
1 | const obj = { |
bind
1 | const obj = { |
防抖
单位时间内,频繁触发事件,只执行最后一次,常用定时器
1 | const box = document.querySelector('.box') |
节流
单位时间内,频繁触发事件,只执行一次.
1 | const box = document.querySelector('.box') |