js进阶知识(作用域、箭头函数、解构、原型、深浅拷贝....)

1、作用域、解构、箭头函数

1.1作用域

1.1.1局部作用域

函数作用域和块作用域
1)函数作用域
只能在函数内部被访问
在这里插入图片描述

2)块作用域
被{}包裹的代码成为代码块,代码块内部声明的变量外部有可能无法被访问

在这里插入图片描述

1.1.2全局作用域

< script>和.js文件的最外层就是所谓的全局作用域
在这里插入图片描述

1.1.3作用域链

作用域链本质上市底层的变量查找机制
1)在函数执行时,优先查找当前函数作用域中查找变量
2)如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域
在这里插入图片描述

1.1.4js垃圾回收机制

1.1.5闭包

1.1.6变量提升

1)把所有var声明的变量提升到当前作用域的最前面
2)只提升声明,不提升赋值
在这里插入图片描述

1.2 函数进阶

1.2.1函数提升

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

在这里插入图片描述

1.2.2函数参数

除了实参、形参,还有动态参数arguments(本质是伪数组。只存在函数中)、剩余参数
剩余参数:

function getSum(...arr){
console.log(arr)
}
getSum(1)
getSum(1,2)
//...是语法符号,置于最末函数形参之前,用于获取多余的实参,且获得的剩余实参,是个真数组,可以使用pop,push等方法
function getSum(a,b...arr){
console.log(arr)
}

展开运算符:
写在外面的叫展开运算符,就不是叫剩余参数了,剩余参数是在函数中使用的。
展开运算符用于求数组最大/小值,合并数组

const arr = [1,2,3]
console.log(Math.min(...arr))

//合并数组
const arr = [1,2,3]
const arr2 = [4,5,6]
const arr3 = [...arr,...arr2]
console.log(arr3)

1.2.3箭头函数

es6新增,使函数表达式更简洁
箭头函数更适用于替代需要匿名函数的地方,
箭头函数不存在函数提升

1)基本语法
//1、
const fn = ()=>{
}
fn()
//2、只有一个形参,可以把小括号去掉
const fn = x=>{
}
//3、只有一行代码的时候,可以省略大括号
const fn = x=> console.log(x)
//4、只有一行代码,无需return,直接返回结果
const fn = x=>x+x
//5、箭头函数可以直接返回一个对象
const fn = uname=>({uname:uname})

2)箭头函数参数

箭头函数没有arguments

const getSum = (...arr)=>{
let sum=0
for(){
}
return sum
}
getSum(1,2,3,4)
3)this
//1、以前的this指向,谁调用这个函数,this就指向谁
//2、箭头函数不会创建自己的this,只会从自己的作用域链的上一层沿用this
//3、对象方法的箭头函数
const obj = {
     sayHi:()=>{
     console.log(this)//指向window
     }
}
const obj = {
     sayHi:function(){
    const count = ()=>{
    console.log(this)//指向obj,这应该看它的上级块作用域,且上一级的块作用域必须是函数,因为函数才有this
    }
     }
}

注意:
<1>DOM事件的回调函数不推荐使用箭头函数,特别是需要用到this的时候
<2>事件回调函数使用箭头函数,this为全局的window

1.3 解构赋值

知道解构的语法及分类,使用解构简洁语法快速为变量赋值

1.3.1数组解构

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

const arr = [100,60,80]
const [max,min,avg] = arr
console.log(max)
//也可以这样写
const [max,min,avg] = [100,60,80]

交换变量

let a = 1
let b = 2;
[a,b]=[b,a]
console.log(a,b)

      // 变量
const [a,b,c] = [1,2,3]//单元值

1)变量多,单元值少,undefined
2)变量少,单元值多
3)剩余参数 变量少,单元值多
4)为了防止有undefined传递单元值的情况,可以设置默认值

const [a = '手机',b = '华为']=['小米']
console.log(a)//小米
console.log(b)//华为

5)按需导入赋值

const [a,b,,d]=[1,2,3,4]
console.log(d)

6)支持多维数组结构

const [a,b,[c,d]]=[1,2,[3,4]]
*加分号的两种情况

1、立即执行函数
2、使用数组开头的时候

1.3.2 对象解构

1)

在这里插入图片描述

const {uname,age} = {uname:'pink老师',age:18}
console.log(uname)
console.log(age)

还可以对对象解构的变量名更改为新变量名

const {uname:username,age} = {uname:'pink',age:18}
console.log(username)
2)解构数组对象
const pig=[
{
  uname:'11',
  age:6
}
]
const [{uname,age}] = pig
console.log(uname)
console.log(age)
3)多级对象解构

在这里插入图片描述
在这里插入图片描述
获得ajax传过来的Msg,是json对象。
在这里插入图片描述

foreach

在这里插入图片描述
不返回数组,不写return,适合遍历数组对象

1.4综合案例

filter

在这里插入图片描述

2、构造函数、数据常用函数

2.1深入对象

2.1.1创建对象

1)字面量
2)new Object({})
3)构造函数

2.1.2构造函数

在这里插入图片描述

构造函数目的是用来快速创建多个类似对象的

function Pig(name,age,gender){
   this.name  = name
   this.age = age
   this.gender = gender
}
const Peppa = new Pig('yhx',6,'nv')

new关键字调用函数的行为是:实例化

2.1.3实例成员&静态成员

在这里插入图片描述

2.2内置构造函数

引用类型:
Object、Array、RegExp、Date
包装类型:
String、Number、Boolean等

2.2.1Object

在这里插入图片描述

2.2.2Array

在这里插入图片描述

reduce

在这里插入图片描述
当数组是对象数组时,应该使用下列代码,且reduce的第二个参数必须要写,写0
在这里插入图片描述
在这里插入图片描述

2.2.3String

在这里插入图片描述

2.2.4Number

在这里插入图片描述

2.3购物车综合案例

处理购物车中的赠品显示:
在这里插入图片描述
购物车案例
在这里插入图片描述

3、深入面向对象

3.1 编程思想

3.1.1面向过程介绍

就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了。

3.1.2面向对象介绍(oop)

面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工。
面向对象编程具有灵活性、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。
面向对象的特性:封装性、继承性、多态性

3.1.3概括,面向对象和面向对象的优缺点

面向过程编程:
优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机就采用的面向对象编程。
缺点:没有面向对象易维护、易复用、易扩展。
面向对象:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更易于维护。
缺点:性能比面向过程低

3.2构造函数

构造函数体现了面向对象的封装特性。
构造函数实例创建的对象彼此独立、互不影响。
构造函数中的方法在每次实例化对象的时候都会在内存的堆中存放每个实例化对象的方法,会浪费内存,可以采用原型,开解决这个问题。

3.3原型

3.3.1原型

①原型:是一个对象。
②原型的作用是:1)共享方法2)可以把那些不变的方法,直接定义在prototype对象上
③构造函数和原型对象里面的this指向实例化的对象
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.2constructor属性

下列代码给出如何防止修改后的原型对象constructor就不在指向当前构造函数,可以在修改后的原型对象中,添加一个constructor指向原型对象。
在这里插入图片描述

3.3.3对象原型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3.4原型继承

继承有原型继承、组合式继承,这里讲的是原型继承。
在这里插入图片描述
将Preson写成构造函数,即可实现Woman的原型中有baby函数,而Man原型中没有baby函数。
如果不使用new Preson()而使用preson对象赋值,会导致Woman和Man的原型中都有baby函数,因为对Woman修改原型,也就是在堆中的preson对象中修改,而Man指向的也是这个被修改的preson对象,所有Man的原型一起被改了。
在这里插入图片描述

3.3.5原型链

对象都有_proto_属性
只要是原型对象都要constructor
在这里插入图片描述
在这里插入图片描述

instanceof

在这里插入图片描述
万物皆对象

3.4综合案例

4、高阶技巧

4.1深浅拷贝

1)浅拷贝

在这里插入图片描述
在这里插入图片描述
浅拷贝缺点:
在这里插入图片描述

在这里插入图片描述

2)深拷贝

在这里插入图片描述

①递归实现深拷贝

在这里插入图片描述
面试:
1、深拷贝就是做到拷贝出来的对象不会影响被拷贝的对象,要想实现深拷贝,就要用到函数递归。
2、普通对象直接赋值就可以,但是对象是数组,再次调用这个函数递归就可以了。
3、如果遇到的是对象形式,再次利用递归把对象解决。
那就是先array后对象o

②lodash

在这里插入图片描述

③json

在这里插入图片描述

4.2异常处理

1)throw抛异常

在这里插入图片描述

2)try /catch捕获异常

在这里插入图片描述
catch中没有throw,要记得写return

3)debugger在这里插入图片描述

4.3处理this

1)this指向

①普通函数的this

在这里插入图片描述
例子:
在这里插入图片描述

②箭头函数的this

在这里插入图片描述
注意:
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述

2)改变this

①call()

在这里插入图片描述
在这里插入图片描述

②apply()

在这里插入图片描述
它跟call不一样的地方就是,形参是以数组的形式传的。
在这里插入图片描述
用apply实现求数组最大/小值:(也可以使用展开元素符求)
在这里插入图片描述

③bind()

在这里插入图片描述
实现定时器中改变this指向:
在这里插入图片描述
总结:
在这里插入图片描述

4.4性能优化

4.4.1防抖debounce

单位时间内,频繁触发事件,只执行最后一次。
使用场景:
1)只需要用户最后一次输入完,在发送请求。
2)手机号、邮箱验证输入检测
实现方法:
1)lodash提供的防抖来处理_.debounce(,)
在这里插入图片描述

2)手写一个防抖函数来处理
分成4步:
在这里插入图片描述

4.4.2 节流 throttle

单位时间内,频繁触发事件,只执行一次
例子:技能冷却
在这里插入图片描述

使用场景:
高频事件:鼠标移动mousemove、页面尺寸缩放resize、滚动条滚动scroll等等
实现方法:
1)lodash提供的节流函数来处理
在这里插入图片描述

2)手写一个节流函数来处理
分3步
在这里插入图片描述

注意:setTimeout无法使用clear清除定时器
在这里插入图片描述

4.4.3 防抖和节流 throttle总结

在这里插入图片描述

4.5综合案例

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天学前端了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值