JavaScript进阶

JavaScript进阶

1.作用域

作用域规定了变量能够被访问的范围

声明变量推荐使用let或者const

2.箭头函数

箭头函数是用来代替匿名函数的

当只有一个形参时,可以省略参数括号

const fn=x=>{

console.log(x)

}
//等同于
const fn=(x)=>{

console.log(x)

}

当箭头函数只有一行代码时,可以省略大括号,并且不用写return

const  fn(x)=>{
console.log(x)
}
//等同于
const  fn(x)=>console.log(x)

可以返回一个对象

const fn=uname=>({name:uname})
console.log(fn('小布'))

3.解构赋值

数组解构

const arr=[20,50,89]
//数组解构赋值
const [a,b,c]=arr
//等同
const a=arr[0]
const b=arr[1]
const c=arr[2]

对象解构

const user={
name:'小明',
age:18
}
在解构赋值时,声明的变量必须与对象内属性名相同
const {name,age}=user

4.Object的静态方法

1.获取对象的所有属性名

const o={name:'小红',age:18}
console.log(Object.key(o))//['name','age']

2.获取对象的所有属性值

const o={name:'小红',age:18}
console.log(Object.values(o))//['小红',18]

3.对象的拷贝(给对象添加属性)

const o={name:'小红',age:18}
const oo={}
Obgect.assign(oo,o)
console.log(oo)//{name:'小红',age:18}
常用于给对象追加一个新键值对
Obgect.assign(o,{sex:'女'})
console.log(o)//{name:'小红',age:18,sex:'女'}

5.Array数组的实例方法

1.forEach ,遍历数组,不返回数组,常用于查找遍历数组元素
2.fifter ,过滤数组,返回新数组,返回的是筛选满足条件的数组元素
3.map ,迭代数组,返回新数组,返回的是处理之后的数组元素,想要使用返回的新数组
4.reduce ,累计器,返回累计处理的结果,常用于求和等
//语法
const arr=[1,5,8]
arr.reduce(function(){},初始值)
arr.reduce(function(上一次值,当前值){},初始值)
//示例
//1.没有初始值
const total=arr.reduce(function(prev,current){
    return prev+current
})//14
//2.有初始值
const total=arr.reduce(function(prev,current){
    return prev+current
},10)//24
//3.箭头函数写法
const total=arr.reduce((prev,current)=>prev+current,10)//24
//4.如果遇到的是数组对象,初始值不能省略,需要写0
const array=[
    {name:'张三',
    salary:1000},
     {name:'李四',
    salary:1000},
     {name:'王五',
    salary:1000}
]
const total=array.reduce((prev,current)=>{
    return prev+current.salary
},0)//3000
5.join,数组元素拼接为字符串,返回字符串
6.find查找元素,返回符合测试条件的第一个数组元素值,如果没有符合条件的就返回undefined
var ages = [3, 10, 18, 20];
 
function checkAdult(age) {
    return age >= 18;
}
 
function myFunction() {
    document.getElementById("demo").innerHTML = ages.find(checkAdult);
}
//输出18
7.every检测数组所有元素是否都符合指定条件,如果所有元素都通过检测返回true,否组返回false
8.some检测数组中的元素是否满足指定条件,如果数组中有元素满足条件返回true,否则返回false
9.concat合并两个数组,返回生成新数组
10.sort对原数组单元值排序
const arr = [49, 5, 14, 89, 71, 3, 10];

// 一般写法
arr.sort(function (a, b) {
    return a - b;   // 按照升序排列 
});

// 箭头函数
arr.sort((a, b) => a - b);

// 结果  [3, 5, 10, 14, 49, 71, 89]

11.splice删除或替换原数组单元,第1个参数为起始下标,第2个为删除个数,第3个为要增加的数据。
12.reverse反转数组
13.findIndex查找元素的索引值
14.slice切片的意思,根据传入的起始和终止下标,获取该范围数组。

6.伪数组转换为真数组

Array.from(arr)

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const lis=document.querySelectorAll('ul li')
console.log(lis)
  //  lis.pop()//报错
    const liss=Array.from(lis)
    console.log(liss)
    liss.pop()
    console.log(liss)
</script>

7.String常见实例方法

1.实例属性length用来获取字符串长度
2.split(‘分隔符’)用来将字符串拆分成数组

把字符串转换为数组

const str='pink,red'
const arr=str.split(',')
console.log(arr)//['pink','red']
3.substring(需要截取的第一个字符的索引[,结束的索引号])用于字符串截取

如果省略 结束的索引号 默认截取到最后

结束的索引号不包含在截取的部分(需要往后+1)

4.startsWith(检测字符串[,检测位置索引号])检测是否以某字符开头
5.includes(搜索的字符串[,检测位置索引号])判断一个字符串是否包含在另一个字符串中,根据情况返回t或f
6.toUpperCase用于将字母转换成大写
7.toLowerCase用于将字母转换成小写
8.indexOf检测是否包含某字符
9.endsWith检测是否以某字符结尾
10.replace用于替换字符串,支持正则匹配
11.match用于查找字符串,支持正则匹配

8.Number

Number是内置的构造函数,用于创建数值

常用方法:toFixed(保留几位小数)

默认保留整数,四舍五入

const price=12.345
//保留两位小数,四舍五入
console.log(price.toFixed(2))//12.35

9.面向对象编程

每一个对象都是功能中心,分工明确

面向对象的特性:封装性、继承性、多态性

10.原型(原型对象)prototype

构造函数封装的方法浪费内存,为了节约内存,使用原型对象

js规定,每一个构造函数都有一个prototype属性,指向另一个对象,所以成为原型对象

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

我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法

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

11.对象原型__proto__

对象会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有_proto_原型的存在

12.原型继承

//男人不能给原型对象prototype添加别的方法或属性,会影响到Perosn的原型对象prototype
const Person={
eyes:2,
head:1
}
//男人构造函数继承  想要继承Person
function Man(){

}
//通过 原型继承 Person
Man.prototype=Person
//构造函数指回Man
Man.prototype.constructor=Man
const aa=new Man()
console.log(aa)
//解决不使用同一对象,但是对象里面包含相同的属性和方法
//男人构造函数继承  想要继承Person
function Man(){

}
//通过 原型继承 Person
Man.prototype=new Person()
//构造函数指回Man
Man.prototype.constructor=Man
const aa=new Man()
console.log(aa)

//女人构造函数继承  想要继承Person
function Woman(){

}
//通过 原型继承 Person
//子类的原型=new 父类
Woman.prototype=new Person()
//给原型对象添加方法
Woman.prototype.baby=function(){
console.log('baby')
}
//构造函数指回Woman
Woman.prototype.constructor=Woman
const bb=new Woman()
console.log(bb)

13.原型链以及instanceof运算符

基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的解构,我们将原型对象的链状结构关系叫做原型链

原型链是一种查找规则,可以查找一些属性和规则,先查找当前的原型对象prototype,没有就查找上一级,也就是——proto——指向的prototype原型对象,如果还没有找到那就查找Object的原型对象,一直查找到Object为null为止

只要是 对象就有__proto__,指向原型对象
只要是 原型对象就有constructor函数,指向构造函数
构造函数.prototype.__proto__指向Object的prototype

instanceof运算符:用来查询构造函数的prototype属性是否出现在某个实例对象的原型链上

console.log(bb instanceof Person)  //true
console.log(bb instanceof Object)  //true
console.log(bb instanceof Array)  //false

14.浅拷贝

因为直接赋值对象后修改对象属性会修改原对象的值,所以有拷贝

浅拷贝:拷贝的是地址,但是当需要拷贝的对象里面还有对象,是会有问题的(像直接复制的问题)

常见方法

1.拷贝对象:Object.assign(空对象,被拷贝的对象) / {…obj} 拷贝对象

2.拷贝数组:Array.prototype.concat() / […arr]

const obj={
name:'小红',
age:18
}
//1.直接复制,会改变原有对象的值
const o=obj
console.log(o)  //{name:'小红',age:18}
o.age=20
console.log(o)  //{name:'小红',age:20}
console.log(obj)  //{name:'小红',age:20}
//2.浅拷贝
const o={...obj}
console.log(o)  //{name:'小红',age:18}
o.age=20
console.log(o)  //{name:'小红',age:20}
console.log(obj)  //{name:'小红',age:18}
//2.1浅拷贝的另一种
const o={}
Object.assign(o,obj)
console.log(o)  //{name:'小红',age:18}
o.age=20
console.log(o)  //{name:'小红',age:20}
console.log(obj)  //{name:'小红',age:18}


15.深拷贝

https://www.lodashjs.com/ 封装好的一个js库 里面有很多方法 包括深拷贝

深拷贝拷贝出来的新对象不会影响旧对象,需要用到函数递归,当我们对普通类型的对象进行拷贝时可以直接赋值,如果遇到对象里面有数组的,需要再次调用这个递归函数,如果遇到对象里包含对象,再次去调用这个递归函数处理对象,先array再对象

const obj={
name:'小红',
age:18hobby:['篮球','足球'],
family{
baby:'小小'
}
}
const o={}
//拷贝递归函数
function deepCopy(newObj,oldObj){
    for(let k in oldObj){
        //处理数组的问题  ,必须先处理数组在处理对象,因为数组也属于对象
        if(oldObj[k] instanceof Arrray){
            newObj=[]
            deepCopy(newObj[k],oldObj[k])
        }else if(oldObj[k] instanceof object){
            newObj={}
            deepCopy(newObj[k],oldObj[k])
        }else{
            //k时属性名 name,age  oldObj[k]时属性值 小红 18
            newObj[k]=oldObj[k]
        }
    }
}

使用json实现深拷贝

JSON的方法:

JSON.parse把json字符串转换为对象

JSON.stringfy把对象转换为json字符串

const obj={
name:'小红',
age:18hobby:['篮球','足球'],
family{
baby:'小小'
}
}
const o=JSON.parse(JSON.stringfy(obj))

16.this指向

箭头函数内不存在this,沿用上一级的

构造函数,圆形函数,dom事件函数等等,不适用箭头函数

17.改变this指向

call 和 apply 区别: call 和 apply 都是可以改变this 指向的问题, call 方法中传递参数要求一个一个传递参数。 但是apply 方法要求传递参数是一个数组形式。
bind的不同之处在于bind会返回一个新的函数。如果需要传参,需要再调用该函数并传参

call() apply() bind()

1.call()

const obj={
name='小红'
}
function fn(){
    console.log(this) //this指向window
}
//call的作用  1.调用函数, 2.改变this指向
fn() //this指向window
//call(需要指向的对象,参数1,参数2)
fn.call(obj)//此时this指向obj

2.apply()

const obj={
name='小红'
}
function fn(){
    console.log(this) //this指向window
}
//apply的作用  1.调用函数, 2.改变this指向 3.返回值
fn() //this指向window
//apply(需要指向的对象,[参数1,参数2])
fn.apply(obj)//此时this指向obj

3.bind()

const obj={
name='小红'
}
function fn(){
    console.log(this) //this指向window
}
//bind的作用  1.不会调用函数, 2.能改变this指向 3.返回值 返回值是个拷贝原函数的函数(新函数是更改this指向的)
fn() //this指向window
//bind(需要指向的对象,参数1,参数2)
fn.bind(obj)//此时this指向obj
fn.bind(obj)(参数)

18.防抖

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

防抖函数的核心:利用setTimeout定时器来实现的

1.声明定时器变量

2.每次鼠标移动(事件触发)的时候要先判断是否有定时器,如果有先清除以前的定时器

3.如果没有定时器,则开启定时器,存入到定时器变量里面

4.定时器里面写函数调用

function debounce(fn,t){
let timer
//return 一个匿名函数
return function(){
if(timer) clearTimerout(timer)
timer=setTimerout(function(){
fn()//调用fn函数
},t)
}
}
box.addEventListener('mousemove',debounce(mouseMove,500))

19.节流

节流:单位时间内,频繁触发事件,只执行一次

节流函数的核心:利用setTimeout定时器来实现的

1.声明定时器变量

2.每次鼠标移动(事件触发)的时候要先判断是否有定时器,如果有定时器 则不开启新的定时器

3.如果没有定时器,则开启定时器,存入到定时器变量里面

3.1定时器里面调用执行的函数

3.2.定时器里面要把定时器清空

function throttle(fn,t){
let timer=null
//return 一个匿名函数
return function(){
if(!timer) {
   timer=setTimerout(function(){
fn()//调用fn函数
       timer=null//清空定时器
},t) 
}

}
}
box.addEventListener('mousemove',throttle(mouseMove,500))

案例:播放视频,退出后重新刷新或进入展示播放进度

//1.获取元素(元素装的是视频) 要对视频进行操作
const video=document.querySelector('video')
video.ontimeupdate=_.throttle(()=>{
//console.log(video.currentTime) 获得当前视频时间
localStorage.setItem('currentTime',video.currentTime)
},1000)
//打开页面触发事件,从本地存储里面去除记录的时间,赋值给video.currentTime
video.onloadeddata=()=>{
video.currentTime=localStorage.getIiem('curentTime')||0
}
  • 30
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值