目录
1.面向过程1.1 面向过程 : 以 “过程” 为核心的编程思想
2.面向对象2.1 面向对象 : 以 “对象” 为核心的编程思想面向对象编程思想三大特征: 封装 、 继承 、 多态
首先说下我的个人理解,作为js基础之后的进阶课程,其实只要基础理解了,它的难度并不大,主要是还是学函数和对象,只是会多一些更多的嵌套,然后改变一下名字,咋一听云里雾里,实际一剖析,还是对象跟函数的一些进阶用法(因为会加入个人理解篇幅较长,另外个人理解只是帮助理解,每个人理解不一样,还是要亲们自己琢磨下)
1.对象
1.面向过程
1.1 面向过程 : 以 “过程” 为核心的编程思想
2.面向对象
2.1 面向对象 : 以 “对象” 为核心的编程思想
面向对象编程思想三大特征: 封装 、 继承 、 多态
1.封装 : 把代码放入 对象的方法中
2.继承(重点) : 一个对象 拥有 另一个对象 所有的成员(属性+方法)
3.多态 : 一个对象 在不同情况下的 不同状态
* js基本不涉及多态
3.构造函数
3.1 工厂函数: 创建对象的函数
3.2 构造函数(顶级重点)
(1) 构造函数:使用 new 关键字调用的函数,其作用与工厂函数一致,都是用来创建对象的,但是语法更简洁
(2) 构造函数new工作原理
a.创建一个空的对象
b.this指向这个对象
c.执行赋值的代码
d.自动返回这个对象
(3) 构造函数new在使用时需要注意的地方
a. return 值类型 : 无效,还是返回new创建的对象
b. return 引用类型: 有效,会覆盖new创建的对象
4.原型对象
4.1 原型对象 : 创建函数的时候,系统会自动创建一个对应的对象,称之为原型对象
4.2 作用 :解决内存浪费 + 变量污染
4.3 构造函数,原型对象,实例对象的关系
a. 构造函数: 有一个prototype属性 指向原型对象
b. 原型对象: 有一个constructor属性 指向构造函数
c. 实例对象: 有一个_proto_属性 指向原型对象
5.静态成员与实例成员
5.1 实例成员 : 实例对象的属性和方法(个人理解:js作者已经编译好的实例对象的属性和方法)
5.2 静态成员: 函数的属性和方法(个人理解:就是js作者已经编译好的函数属性和方法,类似于内置对象)
(1) Object的三个方法
a. 获取对象所有的属性值 : Object.values(对象名)
b. 获取对象所有的属性名 : Object.keys(对象名)
(2) Array伪数组转真数组 : Array.form(伪数组)
6.原型链
6.1 原型链: 每一个对象都有自己的原型,原型也是对象也有自己的原型,以此类推形成链式结构
专业话术: 原型链是js对象的一种查找机制,遵循就近原则
6.2 对象访问原型链规则 :就近原则
先访问自己,自己没有找原型,原型没有找原型的原型,此类类推直到原型链终点null. 如果 还没有,属性则获取undefined, 方法则报错xxx is not funtion
6.3 原型链作用 : 继承
原型继承:把父元素的构造函数实例对象 作为子构造函数的原型对象
语法:子构造函数,prototype = new 父构造函数
6.4 实例对象 instanceof 构造函数
作用:检测构造函数的prototype在不在实例对象的原型链中
7.内置对象
7.1 字符串
(1) indexOf
a.语法: str.indexOf('字符串')
b.作用: 检测字符串在str当中的首字母下标
c.返回值:在str当中,有则返回
(2) split
a.语法: str.split('分隔符')
b.作用: 使用分隔符去切割字符串,得到切割后的数组
c.返回值:数组
(3)substring
a.语法: str.substring(起始下标,结束下标)
b.作用: 截取部分字符串替换,手机号中间替换成****
c.返回值:起始<=截取范围<下标
7.2 数组
(1)reverse
a.语法: arr.reverse()
b.作用: 翻转数组(直接改变原数组)
c.返回值: 翻转后的数组
(2)join
a.语法: arr.join('分隔符)
b.作用: 按照分隔符把数组每一个元素拼接成字符串
c.返回值:字符串
(3)sort
a.语法: arr.sort((a,b) => a-b)
b.作用: 让数组按照 从小到大/从大到小 的顺序排列
c.返回值: 排序好的数组
(4)flat(个人理解:就是把数组里面嵌套的数组全部拿出来,变成一个无嵌套的数组)
a.语法: arr.sort(深度)
b.作用: 平铺(扁平化)数组
c.返回值: 直接修改数组本身
7.3 数组迭代(遍历)
(1) forEach
a.语法: arr.forEach((item,index) => {})
b.作用: 用于遍历数组元素(和for循环一样)
c.返回值:没有返回值
d. 注意:forEach不能中止循环
tra-catch语法可以中止forEach(巧用报错)
try{ arr.forEach( (item,index) => {throw数据} ) }catch(error){error就是throw后面的数据}
(2)map
a.语法: arr.map((item,index) => 新数组元素)
b.作用: 把旧数组变成新数组(映射数组)
c.返回值:新数组
(3)filter
a.语法: arr.filter((item,index) => 布尔值)
b.作用: 筛选功能
c.返回值:筛选之后的数组
(4)every
a.语法: arr.every((item,index) => 布尔值)
b.作用: 全选框
c.返回值:true:所有元素都满足条件
false:有不满足条件的元素
(5)some
a.语法: arr.some((item,index) => 布尔值)
b.作用: 非空判断
c.返回值:true:有满足条件的元素
false:没有满足条件的元素
(6)reduce
a.语法:arr.reduce( (sum,item,index) = > sum , 0 )
b.作用: 数组元素求和、求数组元素最大值等
c.返回值: 最后一次sum结果
2.函数
1.this指向
1.1 普通函数 函数名() : window
1.2 对象方法 对象名.方法名():对象
1.3 构造函数 new 函数名():new创建的实例对象
2.函数上下文调用
作用:修改函数内部的this指向
2.1
函数名.call (修改之后的this,参数1,参数2...)
应用: 万能数据类型检测
Object.prototype.toString.call (数据)
2.2
函数名.apply (修改之后的this,数组/伪数组)
应用: 伪数组转真数组
2.3
函数名.bind (修改之后的this)
应用: 万能数据类型检测
Object.prototype.toString.call (数据)
注意点 :
1. 不会立即执行函数,而是得到一个修改this之后的新函数。
2. bind一般用于修改: 定时器函数、事件处理函数
应用 : 修改定时器的this指向
相同点: 修改函数的this指向
不同点:
(1)传参方式不同 : call是参数列表传参,apply是数组传参
(2)执行机制不同 : call和apply会立即执行,bind不会立即执行,而是得到一个修改this后的新函数
浅拷贝:
地址拷贝 (修改数据对原数据有影响)
Objcet.assign(目标对象,源对象)
(修改基本数据类型对原数据没有影响,修改复杂数据类型对原数据有影响)
深拷贝
方式一(推荐) :
JSON方式实现 先对象转JOSN字符串,再JSON字符串转JS就完成深拷贝了
语法: let newObj = JSON.parse( JSON.stringify( js对象 ) )
方式二(递归) :
//newObj是拷贝后的对象,obj是拷贝的对象
function cloneDeep(newObj, obj) {
// 遍历对象属性,拷贝赋值
for (let key in obj) {
if (obj[key] instanceof Array) {
//声明空数组
newObj[key] = []
//递归
cloneDeep(newObj[key], obj[key])
} else if (obj[key] instanceof Object) {
//声明空数组
newObj[key] = {}
//递归
cloneDeep(newObj[key], obj[key])
} else {
newObj[key] = obj[key]
}
}
}
方式三(lodash) :
_.cloneDeep(js对象)
3.闭包函数
什么是闭包(每个说法都是有依据的):
(1)闭包是 访问了另一个函数局部变量的 函数
(2)闭包是组合 = 函数 + 引用其他函数局部变量 (上下文引用)
(3)闭包就是JavaScript中的空气, 它无处不在
闭包作用:解决变量污染
4.递归函数
什么是递归:一个函数 在内部 调用自己
递归作用:深拷贝(见上部分代码块)
5.箭头函数
语法:
const 函数名 = () => {}
(1) 把function替换成 =>
(2)把形参的小括号移到箭头左边
注意点
(1) 只有一个形参,就可以省略形参小括号(没有形参不能省略)
(2) 函数体只有一行,则可以省略大括号,此时必须省略return
return和大括号,要么都省,要么都不省
与function函数区别
(1) 写法不同
(2) 最大区别:
箭头函数没有this,本质是访问上级作用域的this
(3) 箭头函数不能作为构造函数
6.防抖函数
防抖函数(debounce)
什么是防抖函数:在单位时间内频繁触发事件,只会触发最后那一次
流程:
1. 声明全局变量存储定时器ID(使用一次性定时器)
2. 每一次触发事件,先清除上一次定时器,然后将事件处理代码放入本次定时器
应用场景:输入框搜索
7.节流函数
什么是节流函数:单位时间内频繁触发事件,只会触发一次
流程:
1. 声明全局变量存储上一次触发交互时间
2. 每一次触发事件, 获取当前时间 与 上一次时间做比较。判断是否超过节流间隔
3. 如果 超过节流时间,则执行事件处理代码。 并且存储本次触发时间。
应用场景:滚动条事件
8.拓展:播放器video事件
视频加载好了触发:loadeddata
存储视频播放时间:timeupdate
ES6
1.var与let的区别
(1) 预解析:var声明提前到作用域最顶端
var 有
let 没有
(2) 块级作用域
var没有
let 有
2.解构赋值:变量赋值的简写
对象的解构
(1) 把对象的属性赋值给变量
let {变量名,属性名:变量名 } = 对象名
(2) 把变量值赋值给 对象属性
let 对象名 = {
变量名, // 属性名:变量名
方法名(){}
}
函数的参数结构
function fn( {变量名} ){
方法名
}
fn({name:'张三',age:20})
3.展开运算符
语法: ...
相当于对象/数组遍历的简写
4.Set
数据类型 Set : 集合
* Set相当于是数组类型, 和数组Array唯一的区别是不能存储重复元素
注意:用Set以后数组会变成对象,需要用[...new Set(数组)]转成数组
场景 : 数组去重
let newArr = [ ...new Set(需要去重的数组) ]
5.arguments与剩余函数
arguments
获取函数所有的实参,得到一个伪数组
语法:在函数里面加 arguments
剩余函数:function(...形参){ }
*得到的真数组
如果有多个参数...形参只能写在最后,这样获取的就是除了前面n个形参后面的实参
与arguments作用一致都是获取函数实参,一般用于封装参数不确定的函数
注意:arguments不能用于箭头函数,剩余函数可以
6.lodash实现防抖
链入lodash
_.debounce( 事件处理函数,防抖间隔 )
例如:
let input = document.querySelector('input')
input.addEventListener('input',_.debounce(function(){
console.log(input.value)
},500))
节流:_.throttle(事件处理函数,节流时间间隔)