首页 > 其他分享 >js

js

时间:2023-07-24 23:23:24浏览次数:39  
标签:function console 函数 js const fn log

第一天:作用域&解构&箭头函数

1.作用域

1.1 局部作用域
  • 函数作用域

    在函数内部声明的变量只能在函数内部被访问,外部无法直接访问

  • 块作用域

    使用{}包裹的代码成为代码块,代码块内部声明的变量外部将[有可能]无法被访问(var声明的会被访问,let和const声明的不会被访问)

1.2 全局作用域

在函数体和代码块以外的地方声明的变量成为全局变量,可以被所有函数和代码块共享

1.3 作用域链

作用域链:本质上是底层的变量查找机制

1.在函数被执行时,会优先查找当前函数作用域中查找变量

2.如果查找不到会依次逐级查找父级作用域直到全局作用域

1.4 垃圾回收机制

1.内存分配:当我们声明变量、函数、对象时,系统会自动为他们分配内存

2.内存使用:即读写内存,也就是使用变量、函数等

3.内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存

说明:全局变量一般不会回收(关闭页面回收)

内存泄漏:指程序中分配的内存由某种原因程序未释放或无法释放

方法:1.引用计数法 2.标记清除法

1.5 闭包

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

闭包 = 内层函数 + 外层函数的变量 (可能造成内存泄漏)

  • 闭包作用:封闭数据,提供操作,外部也可用于访问函数内部变量,实现数据的私有

    function outer(){
        let i = 1
        function fn(){
            console.log(i)
        }
        return fn  //返回一个函数用于接收
    }
    const fun = outer()
    fun()   //1
    
1.6 变量提升

1.在代码执行前会先将var声明的变量提到当前函数作用域的最前面

2.只提升声明变量,不提升变量的赋值

2.函数进阶

2.1 函数提升

1.会把所有函数声明提升到当前作用域的最前面

2.只提升函数声明,比提升函数调用

3.函数表达式必须先声明后调用

2.2 函数参数
  • 2.2.1 动态参数

    • arguments:是函数内置的伪数组变量,它包含了调用函数时传入的所有实参

      //求和函数,计算所有参数的和
      function sum(){
          let s = 0
          for(let i = 0;i<arguments.length;i++){
              s + = arguments[i]
          }
          console.log(s)
      }
      //调用求和函数
      sum(5,10)  //两个参数
      sum(1,2,4) //三个参数
      
  • 2.2.2 剩余参数

    允许我们将一个不定数量的参数表示为一个数组

    function getSum(...other) {
    	// other 得到[1,2,3]
    	console.log(other)
    }
    getSum(1,2,3)
    
    • 1.是语法符号,置于最末函数形参之前,用于获取多余的实参

    • 2.借助获取的剩余实参,是个真数组

      function config(baseURL,...other) {
      	console.log(baseURL)  //baseURL 得到 'http://baidu.com'
      	console.log(other)   // other 得到['get','json']
      }
      config('http://baidu.com','get','json')
      
  • 2.2.3展开运算符:将一个数组进行展开

    const arr = [1,5,3,8,2]
    console.log(...arr)  //  1,5,3,8,2
    
2.3 箭头函数

目的:更简短的函数写法并且不绑定this,箭头函数语法更简洁

  • 2.3.1 语法:

    • 1.基本语法:

      const fn = () => {
          console.log('俺是箭头函数')
      }
      fn()
      
    • 2.只有一个参数时可以省略小括号

      const fn = x => {
          return x + x
      }
      console.log(fn(1))  // 2
      
    • 3.如果函数体只有一行代码,可以写到一行上,并且无需写return直接返回值

      const fn =(x,y) => x + y
      console.log(fn(1,2))  // 3
      
    • 4.加括号的函数体返回对象字面量表达式

      const fn = uname => ({uname:uname}) 
      //第一个uname:属性名,第二个uname:属性值
      console.log(fn('刘德华')) 
      
  • 2.3.2 箭头函数参数

    1.无arguments动态参数

    2.有剩余参数

    const getSum(...args) => {
        let sum = 0
        for(let i = 0;i<args.length;i++){
            sum + = args[i]
        }
        return sum
    }
    console.log(getSum(1,2,3))  // 6
    
  • 2.2.3 箭头函数this

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

    const user = {
        name:'小明',
        sleep:function(){
            console.log(this)  //指向user
            const fn = () =>{
                console.log(this) //指向this
            }
            fn()
        }
    }
    user.sleep()
    

3.解构赋值

3.1数组解构

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

语法:

const [a,b,c] = [1,2,3]  //等同于下面的代码
//普通数组
const arr = [1,2,3]
//批量声明变量a,b,c  同时将数组单元值依次赋值给变量a,b,c
const [a,b,c] = arr
-----------------------------------------------------------------------
//交换两个变量
let a = 1
let b = 2;   //这里必须加分号
[b,a] = [a,b]
console.log(a)  //2
console.log(b)  //1
3.2对象解构

本质是将对象属性和方法快速批量赋值给一系列变量的简洁语法

注意:1.只会赋值给与属性名相同变量名(没有则返回undefined)

​ 2.定义的变量名不能与前面的代码名相同,如果要相同则必须对变量进行改 名

方法:就变量名:新变量名

const uname = 'red老师'
const {uname:username,age} = {uname:'pink老师',age:18}
  • 多级对象解构

    const pig = {
        name:'佩奇',
        family:{
            mother:'猪妈妈',
            father:'猪爸爸',
            brother:'乔治'
        },
        age:6
    }
    //进行解构
    const {name,family:{mother,father,brother}} = pig
    

第二天:构造函数&数据常用函数

1.深入对象

1.1 创建对象的三种方式
  • 1.利用对象字面量创建对象

    const obj = {
        name:'佩奇'
    }
    
  • 2.利用new Object

    const obj = new Object({name:'佩奇'})
    console.log(obj)   //  {name:'佩奇'}
    
  • 3.利用构造函数创建对象

    function Pig(name,age,gender){
        this.name = name
        this.age = age
        this.gender = gender
    }
    //创建对象
    const Peppa = new Pig('佩奇',6,'女')
    
1.2 构造函数

是一种特殊的函数,主要用来初始化对象,可以通过构造函数快速创建多个类似的对象

注意:1.它们的命名以大写字母开头

​ 2.它们只能由“new”操作符来执行

​ 3.无参数时可以省略()

​ 4.无return,返回值即为创建的对象

function Pig(name,age,gender){
    this.name = name
    this.age = age
    this.gender = gender
}
//创建对象
const Peppa = new Pig('佩奇',6,'女')
1.3 实例成员&静态成员
  • 1.实例成员

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

  • 2.静态成员

    构造函数的属性和方法成为静态成员

    说明:1.静态成员只能构造函数来访问

    ​ 2.静态方法中的this指向构造函数

2.内置构造函数

引用类型:Object、Array、RegExp(正则)、Data等

包装类型:String、Number、Boolean等

2.1 Object
  • 1.Object.keys:静态方法获取对象中所有的属性(键)

    const o = {name:'佩奇',age:6}
    //获得对象的所有键,并返回一个数组
    const arr = Object.keys(o)
    console.log(arr)  // ['name','age']
    
  • 2.Object.values:静态方法获取对象中所有的属性值

    const o = {name:'佩奇',age:6}
    //获得对象的所有键,并返回一个数组
    const arr = Object.values(o)
    console.log(arr)  // ['佩奇', 6]
    
  • 3.Object.assign:静态方法常用于对象拷贝

    // 拷贝对象  把 o 拷贝给 obj
    const o = {name:'佩奇',age:6}
    const obj = {}
    Object.assign(obj,o)
    console.log(obj)  // {name:'佩奇',age:6}
    
2.2 Array
  • 主要方法

    方法 作用 说明
    forEach 遍历数组 不返回数组,经常用于查找遍历数组元素
    filter 过滤数组 返回新数组,返回的是筛选满足条件的数组元素
    map 迭代数组 返回新数组,返回的是处理之后的数组元素
    reduce 累计器 返回累计处理的结果,经常用于求和等
  • 其他方法

    方法 说明
    join 数组元素拼接为字符串,并返回字符串
    find 查找元素,返回符号测试条件的第一个数组元素值,没有则返回undefined
    every 检测数组所有元素是否都符和指定条件,都符号返回true,否则返回false
    some 检测数组所有元素是否满足指定条件,有元素满足返回true,否则返回false
    concat 合并两给数组,返回生成的新数组
    sort 对原数组单元值排序
    splice 删除或替换原数组单元
    reverse 反转数组
    findIndex 查找元素的索引号
    Array.from 将伪数组转换成真数组
2.3 String
  • 常用实例方法

    方法和属性 说明
    length 获取字符串的长度
    split(‘分隔符’) 用来将字符串拆分成数组
    substring(需要截取的第一个字符的索引号,结束的索引号) 用于字符串截取
    startWith(检测字符串[,检测位置的索引号]) 检测是否以某字符开头
    endWith() 检测是否以某字符结尾
    includes(搜索的字符串[,检测位置的索引号]) 判断一个字符串是否包含在另一个字符串中,返回true或false
    toUpperCase() 将字母转换成大写
    toLowerCase() 将字母转换成小写
    indexOf() 检测是否包含某字符
    replace() 用于替换字符串,支持正则匹配
    match() 用于查找字符串,支持正则匹配
    String()或toString() 强制转换成字符串
2.4 Number
  • toFixed():设置保留小数位的长度

    // 数值类型
    const price = 12.345
    // 保留两位小数 四舍五入
    console.log(price.toFixed(2))  // 12.34
    

第三天:深入面向对象

1.编程思想

1.1面向过程

指分析出解决问题所需的步骤,然后用函数把这些步骤一步一步实现,使用时在一个个的调用

1.2面向对象(oop)

指把事务分解成为一个个对象,然后由对象之间分工与合作

特性:封装性、继承性、多态性

2.原型

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

2.构造函数中有一个prototype属性,指向另一个对象,所以也称为原型对象

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

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

5.把那些不变的方法,直接定义在prototype对象上,可以实现所有对象的实例的共享

2.1 constructor 属性

原型对象中的属性,指向构造函数

Star.prototype = {
    // 重新指回创造这个原型对象的构造函数
    constructor:Star,
    sing:function(){
        console.log('唱歌')
    },
    dance:function(){
        console.log('跳舞')
    }
}
2.2 对象原型

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

注意:1.__proto__是js非标准属性

​ 2.[[prototype]]__proto__意义相同

​ 3.用来表明当前实例对象指向哪个原型对象prototype

​ 4.__proto__对象原型里也有一个constructor属性,指向创建该实例对象的构造函数

2.3 原型继承

继承是面向对象编程的另一个特征,可以进一步提升代码的封装程度,JavaScript中大多是借助原型对象实现继承

function Person(){
    this.eyes = 2
    this.head = 1
}
function Woman(){  }
Woman.prototype = new Person()  // 实现原型继承
Woman.prototype.constructor = Woman  // 重新使原型对象指向构造函数
2.4 原型链

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

2.5 instanceof运算符

用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上

第四天:高阶技巧

1.深浅拷贝

注意:只针对引用类型

1.1 浅拷贝

拷贝的是地址,修改拷贝的对象的值不会改变原对象的值

const obj = {
    uname:'pink',
    age:18
}
// 方法一
const o = {...obj}
// 方法二
const o = {}
Object.assign(o,obj)
// 数组就用Array.prototype.concat() 和 [...arr]
1.2 深拷贝

拷贝的的是对象,不是地址

  • 1.通过递归实现深拷贝

    const obj = {
        uname:'pink',
        age:18,
        habby:['乒乓球','足球']
    }
    const o = { }
    function deepCopy(newObj,oldObj){
        for(let k in oldObj){  // k为属性名,oldObj为遍历的对象,oldObj[]  
            if(oldObj[k] instanceof Array){
                newObj[k] = []  // habby:[]
                deepCopy(newObj,oldObj)
            }else{
                newObj[k] = oldObj{k}
            }
        }
    }
    
  • 2.lodash / cloneDeep

    <script src='./lodash.min.js'></script>  // 先调用lodash库,才能使用cloneDeep()
    const obj = {
        uname:'pink',
        age:18,
        habby:['乒乓球','足球'],
        family:{
        boby:'小pink'
    	}
    }
    const o = _.cloneDeep(obj)  // 实现深拷贝
    
  • 3.通过JSON.stringify()实现

    // JSON.stringify(obj) 把对象转换为JSON字符串
    // JSON.parse(JSON.stringify(obj)) 把JSON字符串转换为对象
    const obj = {
        uname:'pink',
        age:18,
        habby:['乒乓球','足球'],
        family:{
        boby:'小pink'
    	}
    }
    const o = JSON.parse(JSON.stringify(obj))
    

2.异常处理

2.1throw 抛异常

异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法运行

function fn(x,y){
    if(!x || !y){
        throw new Error('没有参数传递过来')
    }
    return x + y
}
fn()

注意: throw会中断程序

2.2try / catch 捕获异常
<p>123</p>
<script>
    function fn(){
    	try{
            // 可能发生错误的代码写到try中
            const p = document.querSelector('.p') //p标签获取错误
            p.style.color = 'red'
        }catch(err){
            // 拦截错误,提示浏览器提供的错误信息,不中断程序的运行
            console.log(err.message)  // 不会执行try中的内容,并且抛出错误信息
            retuen  // 中断程序
        }finally{
            // 不管程序是否正确,一定会去执行的代码
            alert('弹出对话框')
        }
    console.log(11)  // 11 会继续执行,不会中断程序
}
</script> 
2.3debugger
const arr = [1,3,5]
const newArr = arr.map((item,index) =>{
    debugger   //  相当于给程序打断点
    console.log(item)
    console.log(index)
    return item + 10
})
console.log(newArr) // [11,13,15]

3.处理this

3.1 this指向
  • 开启严格模式

    'use strict'  // 严格模式下没有调用者this指向undefined
    function fn(){
        console.log(this)  // undefined
    }
    fn()
    
3.2 改变this
  • 3.2.1 call(): 使用call()方法调用函数,同时指定被调用函数中this的值

    语法: 注意:不需要指向时可以设为null

    fun.call(thisArg,arg1,arg2,...)
    // thisArg: 在fun函数运行时指定的this的值
    // arg1,arg2: 传递的其他参数  
    const obj = {
             age:18
    }
    function fn(x,y){
        console.log(this)   // 指向obj
        console.log(x + y)  //3
    }
    fn.call(obj,1,2) 
    
  • 3.2.2 apply(): 使用call()方法调用函数,同时指定被调用函数中this的值

    语法:

    fun.apply(thisArg,[argsArray])
    // thisArg: 在fun函数运行时指定的this的值
    // argsArray: 传递的值,必须包含在数组里面
    const obj = {
             age:18
    }
    function fn(x,y){
        console.log(this)    // 指向obj
        console.log(x + y)   //3
    }
    fn.apply(obj,[1,2]) 
    

    应用场景:求最大值

    const arr = [100,44,77]
    const max = Math.max.apply(null,arr)
    const min = Math.min.apply(null,arr)
    console.log(max,min)   //  100 44
    
  • 3.2.3 bind(): bind()方法不会调用函数

    语法:

    fun.apply(thisArg,[argsArray])
    // thisArg: 在fun函数运行时指定的this的值
    // arg1,arg2: 传递的其他参数  
    const obj = {
             age:18
    }
    function fn(x,y){
        console.log(this)    // 指向obj
        console.log(x + y)   //3
    }
    fn.bind(obj,[1,2]) 
    

    注意:返回由指定的this值和初始化参数改造的原函数拷贝(新函数)

4.性能优化

4.1 防抖(debounce)

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

  • 利用防抖处理-鼠标滑过盒子显示文字(要求鼠标在盒子上移动,鼠标停止500ms后, 数字才加一)

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
        box.innerHTML = i++
    }
    box.addEventListener('mousemove',mouseMove)
    
  • 1.lodash提供的防抖

    _.debounce(func,[wait=0],[options=]) 
    //  func:要防抖的函数  
    //  wait:需要延迟的毫秒数 
    //  func:选项对象  
    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
        box.innerHTML = i++
    }
    box.addEventListener('mousemove',_.debounce(mouseMove,500))                    
    
  • 2.手写一个防抖的函数

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
        box.innerHTML = i++
    }
    function debounce(fn,t){
        let timer
        return function(){
            if(timer) clearTimeout(timer)
            timer = setTimeout(function(){
            fn()
        },t)
      }
    }
    box.addEventListener('mousemove',debounce(mouseMove,500))
    
4.2 节流(throttle)

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

  • 利用节流处理-鼠标滑过盒子显示文字(要求鼠标在盒子上移动,不管移动多少次,每隔500ms才加一)

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
        box.innerHTML = i++
        // 如果存在开销较大操作,大数据处理,大量dom操作,可能会卡
    }
    box.addEventListener('mousemove',mouseMove)
    
  • 1.lodash提供的节流函数

    _.throttle(func,[wait=0],[options=]) 
    //  func:要防抖的函数  
    //  wait:需要延迟的毫秒数 
    //  func:选项对象  
    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
        box.innerHTML = i++
    }
    box.addEventListener('mousemove',_.throttle(mouseMove,500))                           
    
  • 2.手写一个节流的函数

    const box = document.querySelector('.box')
    let i = 1
    function mouseMove() {
        box.innerHTML = i++
    }
    function throttle(fn,t){
        let timer = null
        return function(){
            if(!timer){
            timer = setTimeout(function(){
            fn()
            timer = null
            },t)
        }        
      }
    }
    box.addEventListener('mousemove',throttle(mouseMove,500))
    
4.3 事件

说明:video.currentTime: 可以获取当前视频播放的时间

  • 1.ontimeupdate: 事件在视频/音频(audio/video)当前的播放位置发生改变时触发

  • 2.onloadeddata: 事件在当前帧的数据加载完成且还没有足够的数据播放视频/音频(audio/video)的下一帧触发

    const video = document.querySelector('video')
    video.ontimeupdate = _.throttle(()=>{
    	localStorage.setItem('currentTime', video.currentTime)
    },1000)
    video.onloadeddata = ()=>{
    	video.currentTime = localStorage.getItem('currentTime') || 0 
    }
    

标签:function,console,函数,js,const,fn,log
From: https://www.cnblogs.com/yeqiusr/p/17578626.html

相关文章

  • JSTL 标签库详细介绍资料 .
     前言从JSP1.1规范开始,JSP就支持在JSP中使用自定义标签了,自定义标签的广泛使用造成了程序员重复定义,这样就促成了JSTL(JavaServerPagesStandardTagLibrary)的诞生。作者:丁令JSTL简介JSTL是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。JSTL只......
  • Rxjs 入门
    RxJS(ReactiveExtensionsforJavaScript)是一个用于处理异步数据流和事件流的库。它是基于观察者模式和迭代器模式的一种实现,可以帮助开发者更方便地处理复杂的异步操作。RxJS的核心概念是Observable(可观察对象)。Observable代表一个可观察的数据源,它可以发出多个值,并在完成或出错......
  • 老杜 JavaWeb 讲解(十四) ——JSP+Servlet改造oa项目
    (十四)JSP改造oa项目相关视频:38-Servlet和JSP改造oa项目使用Servlet+JSP完成oa项目的改造使用Servlet处理业务,收集数据。使用JSP展示数据。将之前原型中的html文件,全部修改为jsp,然后在jsp文件头部添加page指令(指定contentType防止中文乱码),将所有的JSP直接拷贝到web......
  • python jsonpickle模块不序列化私有变量
    jsonpickle模块可以把对象序列化为JSON文件,还是比较方便的.但是并不是所有变量都需要序列化的,比如有些私有变量就不需要序列化,下面是实现方法:importjsonpickleclassNoSerailPrivates:'''表示不序列化私有变量,以_开头都变量'''def__getstate__(self):......
  • Code-OpenSource-JSON for Modern C++ v3.10.5
    Code-OpenSource-JSONforModernC++v3.10.5github.com/nlohmann/jsonhttps://json.nlohmann.me/home/exceptions/#version-historyhttps://json.nlohmann.me/api/macros/json_diagnostics/#extended-diagnostic-messages#defineJSON_DIAGNOSTICS1输出详细信息......
  • JS中文件相关的知识(一):MIME类型
    不知道有没有同学和我一样,写代码时一遇到文件操作就犯怵,必须要先去把知识补一遍再说;对于Content-Type、responseType、ArrayBuffer、buffer、blob、file等这些词汇,心里问号一大堆,从来都没有真正区分清楚过;这样下去不是办法呀,真的猛士,应该敢于...一百次浮于表面,不如一次深入骨髓。......
  • 前端请求报错:'JSON parse error: syntax error, expect {, actual e…1, line 1, colu
    1、如果不用JSON.stringify(inputJson)包起来就会报错letinputJson={"selectUid":selectUid};varresponse=await$.ajax({type:'POST',url:'xxx',data:inputJson,//正确的是JSON.stringify(inputJson)......
  • ts项目引用js文件
    1、template- index.html-head添加:  <script type="text/javascript" src="<%= BASE_URL %>assets/lib/jquery.js"></script>2、types-j-query.d.ts添加: declare module 'jQuery'3、vue.config.js- configureWebpack-e......
  • SyntaxError: Expected property name or ‘}‘ in JsoN atposition 1
    1、在代码中通过JSON.parse()进行转换,发现如下图所示报错了。其实主要原因是单引号和双引号引起的问题。如果转义的字符串进行了赋值,那么上面一层代码会多了一层的转义。这里加2个JSON.parse()是因为,第一次转换的时候还是个字符串。我们要在json字符串前后手动加上双引号,然后在进......
  • Node.js入门 - 永恒的Hello World!
    文章原作者为LeeJacobson,已经作者授权翻译用于非商业用途。介绍 这是我的关于Node.js系列入门教程的第一篇。必须说明一下,我并不是Node.js的专家,但是尝试向别人解释这是怎么回事是自我学习的一个好方法。如果你发现有些地方并不是那么正确,请提出来让我知道以便修正,谢之。 最近......