JS进阶笔记

Day01 ES6

  1. 作用域(scope)——规定了范围

  1. 局部作用域

~函数作用域

~块作用域 let, const可能产生块作用域. var不能

  1. 全局作用域

减少全局变量使用, 后面在垃圾回收机制中会讲

  1. 作用域链

~本质上是底层的变量查找机制

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

~子作用域能访问父作用域, 父作用域不能访问子作用域

  1. 垃圾回收机制

~内存的生命周期:内存分配 — 内存使用 — 内存回收

~全局变量不回收

~局部变量的值,不用了就会回收

~内存泄露:不再用到的内存,没有及时释放,就叫做内存泄漏

~常见垃圾回收算法:引用计数法和标记清除法

引用计数法:嵌套引用会造成内存泄漏

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

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

~简单理解:闭包 = 内层函数 + 外层函数的变量

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

~应用:实现数据的私有

~可能存在内存泄漏

  1. 变量提升— 只针对var,let 和 const 没有,实际开发不推荐

~把所有var声明提升到当前作用域的最前面,只提升声明,不提升赋值

  1. 函数提升:函数表达式必须先声明和赋值,后调用;否则报错

~把所有函数声明提升到当前作用域的最前面,只提升声明,不提升调用

例:

相当于——>

  1. 函数进阶

  1. 动态参数(伪数组) arguments

~伪数组,只存在函数中

  1. 剩余参数(真数组)提倡使用

~在函数内部使用

  1. 展开运算符

~用于数组展开

~求数组最大值

~合并数组

  1. ⭐⭐⭐箭头函数⭐⭐⭐

~语法1:基本写法

~语法2:只有一个参数可以省略小括号

~语法3:如果函数体只有一行代码,可以写到一行上,并且无需写 return 直接返回值

~语法4:加括号的函数体返回对象字面量表达式

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

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

  1. 解构赋值

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

~基本语法:

const arr = [1, 2, 3]

const [a, b, c] = arr

console.log(a)

console.log(b)

console.log(c)

~两个变量快速互换赋值

let a = 0

let b = 1; // 必须加分号

[a, b] = [b, a]

console.log(a, b)

~冒泡排序

const arr = [6, 3, 4, 7, 5, 5, 46, 4]

for (let i = 0; i < arr.length; i++) {

for (let j = i + 1; j < arr.length; j++) {

if (arr[j] < arr[i]) {

[arr[j], arr[i]] = [arr[i], arr[j]]

}

}

}

console.log(arr)

~注意: js 前面必须加分号情况

~利用剩余参数解决变量少 单元值多的情况

~ 防止有undefined传递单元值的情况,可以设置默认值

~按需导入,忽略某些返回值:

  1. 对象解构

~基本语法:

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

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

~多级对象解构

  1. ⭐⭐⭐forEach()⭐⭐⭐方法用于调用数组的每个元素,并将元素传递给回调函数

~与map相比它没有返回值

~就是遍历, 加强版的for循环

  1. ⭐⭐⭐filter()⭐⭐⭐

~筛选数组符合条件的元素,并返回筛选之后元素的新数组

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

~ 参数:currentValue 必须写, index 可选

~exp.

简化写法

拓展: 用css实现tab栏切换

  1. 案例

Day02

  1. 深入对象

  1. 创建对象3种方式

~利用对象字面量创建对象

~利用 new Object 创建对象

~利用构造函数创建对象——快速创建多个对象

将公共属性抽取出来

约定:1. 它们的命名以大写字母开头

2. 它们只能由 "new" 操作符来执行

  1. 构造函数

~无需return, 默认返回值是创建的新对象

~new ... 是实例化

~实例化执行过程:

1.创建新对象

2.构造函数this指向新对象

3.执行构造函数代码,修改this,添加新的属性

4.返回新对象

  1. 实例成员&静态成员

~实例成员:通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员

~静态成员:构造函数的属性和方法被称为静态成员,只能通过构造函数访问

  1. 内置构造函数

  1. Object

3种静态方法

~Object.keys 静态方法获取对象中所有属性(键)

~Object.values 静态方法获取对象中所有属性值

~Object.assign 静态方法常用于对象拷贝

  1. Array

~reduce()方法- 累计器

~返回函数累计处理的结果,经常用于求和等

~补充 map, filter, reduce的区别

~map(), filter(), every(), some(), fill(), findIndex(), find()

~伪数组转换为真数组静态方法 Array.from()

  1. String用法

~split() 字符串转换为数组

~substring() 字符串截取

~startsWith()

~includes()

  1. Number用法

~toFixed() 保留小数位数

Day03 面向对象

  1. 编程思想

(1)面向过程:就是分析出解决问题所需要的步骤,然后使用函数把步骤实现,使用时再依次调用

(2)面向对象:是把事务分解成为一个个对象,然后由对象之间分工与合作

封装性、继承性、多态性

  1. 构造函数

(1)是面型对象的重要部分

(2)存在浪费内存的问题

  1. 原型 prototype

  1. 原型

~构造函数通过原型分配的函数是所有对象所共享的

~每个构造函数都有prototype属性, 指向另一个对象Object,也叫原型对象

~这个对象可以挂载函数, 对象实例化不会多次创建原型上的函数,节约内存

~把不变的方法,定义再prototype对象上, 所有的对象的实例可以共享方法

~构造函数和原型对象的this都指向实例化的对象

  1. constructor属性

~每个原型对象里面都有个constructor 属性(constructor构造函数),该属性指向该原型对象的构造函数

~指回原型构造函数

  1. 对象原型__proto__ (只读的)

~对象都会有一个属性 __proto__ 指向构造函数的prototype 原型对象

~__proto__对象原型里也有一个constuctor属性,指向创建该实例对象构造函数

  1. 原型继承

  1. 原型链

~只要是对象就有__proto__

~只要是原型对象就有constructor

~当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。

~如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)

~如果还没有就查找原型对象的原型(Object的原型对象)

~依此类推一直找到Object 为止(null)

~__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

~可以使用instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

~instanceof

Day04

  1. 拷贝

  1. 浅拷贝

~首先浅拷贝和深拷贝只针对引用类型

~浅拷贝:拷贝的是地址

~常见方法:

1.拷贝对象:Object.assgin()/ 展开运算符 {...obj} 拷贝对象

2.拷贝数组:Array.prototype.concat()或者 [...arr]

~问题:

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)

  1. 深拷贝 3种方式

1. 通过递归函数实现深拷贝(简版)

(1)新对象不会影响旧对象

(2)普通拷贝直接赋值,如果是数组用到递归, 用instanceof 筛选出来, 先命名一个空数组,在递归赋值

(3)如果是对象用到递归, 和数组同理

2. js库lodash里面cloneDeep内部实现了深拷贝

3. 通过JSON.stringify()实现

  1. 异常处理

  1. throw抛出异常

1. throw 抛出异常信息,程序也会终止执行

2. throw 后面跟的是错误提示信息

3. Error 对象配合 throw 使用,能够设置更详细的错误信息

  1. try catch finally

总结:

1. try...catch 用于捕获错误信息

2. 将预估可能发生错误的代码写在 try 代码段中

3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息

4. finally 不管是否有错误,都会执行

  1. debugger

  1. this

  1. 普通函数

this指向调用者.

~普通函数没有明确调用者时 this 值为 window,严格模式下没有调用者时 this 的值为 undefined

  1. 箭头函数

1. 箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的

2.箭头函数中的this引用的就是最近作用域中的this

3.向外层作用域中,一层一层查找this,直到有this的定义

~注:在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window

因此DOM事件回调函数如果里面需要DOM对象的this,则不推荐使用箭头函数

~注:同样由于箭头函数this 的原因,基于原型的面向对象也不推荐采用箭头函数

  1. 处理this

  1. call()

fun.call(thisArg,arg1, arg2, ...)

à指向obj

  1. apply()

fun.apply(thisArg,[argsArray])

与call() 相比必须传入数组

使用场景:

  1. bind()

fun.bind(thisArg, arg1, arg2, ...)

返回值是个函数, 是对原函数的拷贝

不会立即调用函数

  1. 三者区别

call和apply会调用函数, 并改变函数内部指向

call和apply传递参数不一样, call传递参数aru1, aru2..形式 apply必须传递数组

bind不会立即调用函数, 可以改变函数内部指向

  1. 主要应用场景

call调用函数并且可以传递参数

apply经常跟数组有关系, 比如借助于实现数组最大值最小值

bind不调用函数, 但是改变this指向, 比如改变定时器内部this指向

  1. 防抖和节流 – 性能优化

  1. 防抖 debounce

单位时间内, 频繁触发事件, 只执行最后一次

所谓防抖,就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间, 会打断函数执行直至触发结束

~手写防抖函数思路:

  1. 节流 throttle

单位时间内, 频繁出发时间, 只执行一次

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数, 不会打断当前函数的执行

使用场景:

~高频事件: 鼠标移动mousemove, 页面尺寸缩放resize, 滚动条scroll

~手写节流函数

  1. 总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值