打卡:JS复习

一 数据类型介绍及值类型和引用类型的理解(8.2)

  1. 基本数据类型:number,string,Boolean,null,undefined,symbol
  2. 引用数据类型:object,Array,function
  3. 值类型是指基本数据类型,每个变量都有自己独立的值。
  4. 引用类型是指除了基本类型以外的类型,变量存储的是一个指向实际对象的引用,对一个变量修改会影响到另一个变量

二 数据类型的判断(8.3)

  1. typeof:判断基本类型,返回数据类型,但是无法判断null和数组
  2. instanceof:用于检查对象是否属于某个特定的类。可以判断数组
  3. Object.prototype.toString:获取一个对象内部的属性
  4. Array.isArray:用于判断一个对象是否为数组类型
    // 用法
    typeof value;
    value instanceof Constructor;
    Object.prototype.toString.call(value);
    Array.isArray(value);

三 实现深拷贝(8.4) 

// 1.使用JSON序列化和反序列化

    JSON.parse(JSON.stringify(obj))

// 2.使用递归复制

    const deepCopy = (obj) => {
        if (typeof obj !== 'object' || obj === null) {
            return obj
        }
        let copy = Array.isArray(obj) ? [] : {}
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                copy[key] = deepCopy[obj(key)]
            }
        }
        return copy
    }

四 根据0.1+0.2 != 0.3,讲讲IEEE754 ,如何让其相等?(8.5)

  1. IEEE754是一种浮点数表示准则,它定义浮点数的存储和运算规则。然而,由于浮点数的二进制表示存在精确限制,导致某些十进制数无法精确表示,从而引发了类似0.1+0.2 != 0.3的场景
  2. 解决办法:
    1. 使用整数运算
    2. 使用toFixed()方法
    3. 使用Math.round()方法

五 原型和原型链(8.7)补8.6

  1. 原型:
    1. 在JS中,每一个对象都有一个原型(prototype)属性,它指向另一个对象或者为null
    2. 原型是一个普通对象,它包含了共享的属性和方法
    3. 当我们访问一个对象的属性或方法时,如果对象本身没有该属性和方法时,JS引擎会沿着原型链往上查找,直到找到该属性或方法
  2. 原型链:
    1. 原型链是由对象的原型组成的链式结构
  3. 作用:
    1. 实现对象之间的继承
    2. 实现属性和方法的共享

六 作用域和作用域链(8.7)

  1. 作用域
    1. 作用域是指变量和函数的可访问范围
    2. JS中有全局作用域和局部作用域(函数作用域和块级作用域)
    3. 全局作用域定义的变量和函数可以在整个代码中访问
    4. 局部作用域中定义的变量和函数只能在其所在的作用域内部访问
  2. 作用域链
    1. 是由多个作用域组成的链式结构
    2. 作用域的顶端是全局作用域
  3. 作用:
    1. 控制变量和函数的可见性和可访问性:可以避免命名冲突和变量污染
    2. 实现变量的封装和保护:通过作用域链,避免外部作用域对变量的直接访问和修改

七 执行上下文(8.8)

  1. 在JS中,执行上下文是指代码执行时的环境,包含了变量,函数和对象等信息。每当JS代码执行时,都会创建一个执行上下文,并且这些执行上下文会行程一个执行上下文栈
  2. 执行上下文包含三个重要组成部分
    1. 变量对象:它存储了在上下文中定义的变量,函数声明和函数参数。在全局上下文中,变量对象被称为全局对象,在函数上下文中,被称为活动对象
    2. 作用域链:
    3. this值:指向当前执行上下文所属对象。在全局下,执行全局对象。在函数下,this的值取决于函数的调用方式
  3. 生命周期
    1. 创建阶段:在创建阶段,JS引擎会创建变量对象,建立作用域和确定this值,同时,函数声明会被提到当前作用域的顶部
    2. 执行阶段:在执行阶段,JS引擎会按照代码的顺序执行,将变量,函数等操作添加到执行栈中执行
    3. 销毁阶段:在执行完成后,执行上下文会被销毁,释放内存空间

八 闭包(8.9)

  1. 闭包是指函数以及其在创建时能够访问的词法环境的组合,简单来说,闭包是由函数和其相关的引用环境组成的包裹
  2. 特点:可以访问其外部函数的变量和参数,即使外部函数以及执行完毕
  3. 优势:
    1. 封装私有变量
    2. 记忆状态
    3. 实现模块化
  4. 缺点:
    1. 内存占用
    2. 性能影响
    3. 变量共享和意外修改
    4. 难以理解和调试
  5. 简单的例子
    function outerFunction(){
        let outerVariable = 'Hello';
        function innerFunction() {
            console.log(outerVariable);
        }
        return innerFunction;
    }
    let closure = outerFunction();
    closure(); 

九 new的实现(8.10)

  1. 实现步骤:
    1. 创建一个空对象,作为新对象的实例
    2. 将新对象的原型指向构造函数的原型对象,已便新对象可以访问构造函数原型上的属性和方法
    3. 将构造函数的this指向新对象
    4. 执行构造函数中的代码,初始化新对象的属性和方法
    5. 如果构造函数没有显式返回一个对象,则返回新对象
  2. 简单例子
    function myNew(constructor, ...arge) {
        // 创建一个空对象,作为新对象的实例
        const obj = {}
    
        // 将新对象的原型指向构造函数的原型对象
        Object.setPrototypeOf(obj, constructor.prototype)
    
        // 将构造函数的this指向新对象,并进行构造函数
        const result = constructor.apply(obj, arge)
    
        // 如果有构造函数有显式返回一个对象,则返回该对象,否则返回新对象
        return typeof result === 'object' && result !== null ? result : obj
    }
    
    // 实例构造函数
    function Person(name, age) {
        this.name = name
        this.age = age
    }
    
    // 使用myNew创建实例对象
    const person = myNew(Person, 'John', 26)
    
    console.log(person.name); // 输出: John
    console.log(person.age); // 输出: 25
    console.log(person instanceof Person); // 输出: true

十 call,apply,bind的实现即应用场景(8.11) 

  1. 都用于改变函数执行上下文(即函数内部this值)的方法
  2. call
    1. 语法:function.call(thisArg, arg1, arg2, ...)
    2. 作用:立即调用函数,并将指定的 this 值和参数传递给函数。可以将任意对象作为函数的上下文,并立即执行函数
    3. 应用场景:常用于借用其他对象的方法,或者在函数内部指定特定的上下文执行
  3. apply
    1. 语法:function.apply(thisArg, [argsArray])
    2. 作用:立即调用函数,并将指定的 this 值和参数数组传递给函数,可以将任意对象作为函数的上下文,并立即执行函数
    3. 应用场景:常用于借用其他对象的方法,或者在函数内部指定特定的上下文执行,与call 不同的是,apply 接受的参数是数组而不是逐个参数
  4. bind
    1. 语法:function.bind(thisArg, arg1, arg2, ...)
    2. 作用:创建一个新的函数,将指定的 this 值和参数绑定到原函数上,返回的新函数可以在稍后的时候调用
    3. 应用场景:常用于场景一个绑定了特定上下文的函数,可以在稍后的时候调用或者用于事件处理函数,定时器回调等需要保持特定上下文的场景

十一 异步(8.12)

  1. 在js中异步是一种处理代码执行顺序的机制。当代码执行到异步操作时,它会被放入事件循环队列中,然后继续执行后续的代码,而不会等待异步操作完成
  2. 常见的场景
    1. 定时器:使用setTimeout或setInterval可以在一定时间间隔后执行回调函数,而不会阻塞后续代码的执行
    2. AJAX请求:通过XMLHttpRequest或现代的fetchAPI发起网路请求时,可以使用回调函数或Promise对象来处理异步响应
    3. 事件处理:当用户与页面进行交互时,例如点击事件,滚动页面等,可以通过事件监听器来处理异步操作
    4. 异步函数:ES6引入了asyns和await语法,可以更方便地处理异步操作,通过在函数前面加上asyns关键字,函数内部使用await关键字来等待异步操作完成

十二 浏览器回收机制(8.14)补8.13

  1. 标记清除(Mark and Sweep)
    1. 当变量不在被引用时,垃圾回收器会将其标记为可回收
    2. 垃圾回收器会从根对象开始遍历,标记所有与根对象相关联的对象
    3. 未被标记的对象将被视为垃圾,将被清除并释放内存
  2. 引用计数(Reference Counting)
    1. 垃圾回收器会为每个对象维护一个引用计数器
    2. 当对象被引用时,引用计数器加一,当对象引用被释放时,引用计数器减一
    3. 当引用计数器为零时,垃圾回收器会将对象标记为可回收的,并释放相关内存
  3. 内存回收的时机
    1. 垃圾回收器会根据一定策略和算法来确定何时执行内存回收
    2. 常见的策略包括标记-清除,标记-整理,分代回收等
    3. 垃圾回收器会在空闲时刻或达到一定的条件时触发内存回收
  4. 避免内存泄漏
    1. 内存泄漏是指不再使用的对象仍然被保留在内存中,无法被垃圾回收器释放
    2. 避免内存泄漏的方法包括及时释放不再使用的对象,避免循环使用,合理使用闭包等

十三 防抖(8.14)

  1. 是一种优化技术,用于限制某个函数在短时间内频繁触发的情况,以减少不必要的计算和网路请求
  2. 原理:在函数被触发后,设置一个定时器,在指定时间间隔内如果函数再次被触发,则清除之前的定时器并重新设置新的定时器,知道指定的时间间隔内没有再次触发函数,才真正执行函数
  3. 常用场景
    1. 输入框搜索
    2. 窗口调整
    3. 按钮点击
  4. 简单的实例
    function debounce(func, delay) {
        
        let timer
    
        return function() {
        
            const context = this
            const args = arguments
            
            clearTimeout(timer)
            timer = setTimeout(function() {
                func.apply(context, arge)
            }, delay)
        }
    }
    
    function search() {
        // 执行搜索操作
    }
    const debounceSearch = debounce(search, 300)
    input.addEventListener('input', debounceSearch)

十四 节流(8.15)

  1. 是一种限制函数执行频率的技术。它可以确保在一定时间间隔内,函数只会被执行一次,无论触发频率多高

  2. 常用场景

    1. 监听滚动事件

    2. 处理输入框事件

    3. 防止按钮重复点击

  3. 简单实例

    function throttle(func, delay) {
        let lastTime = 0
        return function() {
            const currentTime = Date.now()
            if (currentTime  - lastTime >= delay) {
                func.apply(this, arguments)
                lastTime = currentTime  
            }
        }
    }
    
    const throttledScrollHandler  = throttle(function () {
        // 处理滚动事件的逻辑
    }, 200)
    
    window.addEventListener('scroll', throttledScrollHandler)

十五 继承(8.16) 

  1. 继承是一种通过创建一个新的对象来扩展现有对象的能力,
  2. 实现方式
    1. 原型链继承:通过将子类的原型对象指向父类的实例来实现继承。
      function Parent() {
          this.name = 'Parent'
      }
      Parent.prototype.sayHello = function() {
           console.log('Hello, ' + this.name);
      }
      function Child() {
          this.name = 'Child'
      }
      Child.prototype = new Parent()
      
      let child = new Child()
      
      child.sayHello(); // 输出:Hello, Child
    2. 构造函数继承:通过子类的构造函数中调用父类的构造函数来实现继承
      function Parent() {
          this.name = 'Parent';
      }
      function Child() {
          Parent.call(this)
          this.name = 'Child'
      }
      
      let child = new Child()
      
      console.log(child.name) // 输出:Child
    3. 组合继承:结合原型链继承和构造函数继承的方式,即可以继承父类的属性和方法,又可以拥有自己的属性
      function Parent() {
          this.name = 'Parent'
      }
      
      Parent.prototype.sayHello = funciton() {
          console.log('Hello, ' + this.name)
      }
      
      function Child() {
          Parent.call(this)
          this.name = 'Child'
      }
      
      Child.prototype = new Parent()
      Child.prototype.constructor = Child
      
      var child = new Child()
      child.sayHello() // 输出:Hello, Child
    4. ES6类继承:ES6引入了class和extends关键字,提供了更简洁的语法来实现继承
      class Parent {
          constructor() {
              this.name = 'Parent';
          }
      
          sayHello() {
              console.log('Hello, ' + this.name)
          }
      }
      
      class Child extends Parent {
          constructor() {
              super()
              this.name = 'Child'
          }
      }
      
      let child = new Child()
      child.sayHello() // 输出:Hello, Child

十六 promise 实现(8.17) 

  1. 是一种用于处理异步操作的对象。它可以用来从处理异步操作的成功和失败,并返回响应的结果
  2. 基本实现
    const promise = new Promise((resolve, reject) => {
    
      // 异步操作
      // 如果操作成功,调用 resolve 并传递结果
      // 如果操作失败,调用 reject 并传递错误信息
    
    })
    
    promise.then((result) => {
    
        // 处理操作成功的结果
    
    }).catch((error) => {
    
        // 处理操作失败的错误信息
    
    })

十七 Proxy(8.18) 

  1. 是一种用于创建代理对象的特殊对象。代理对象可以拦截并自定义目标对象的操作,包括属性访问,赋值,函数调用等。proxy提供一种机制,可以在目标对象上进行拦截和修改操作,从而实现对目标对象的动态控制和增强
  2. 基本用法
    const proxy = new Proxy(target, handler);
  3.  可以定义多个拦截操作
    1. get(target, property, receiver):拦截对目标对象属性和读取操作
    2. set(target, property, value, receiver):拦截对目标对象属性和赋值操作
    3. apply(target, thisArg, argumentsList):拦截对目标对象的函数调用
    4. has(target, property):拦截in操作符
    5. deleteProperty(target, property):拦截delete操作符
    6. getOwnPropertyDescriptor(target, property):拦截Object.getOwnPropertyDescriptor()方法
    7. defineProperty(target, property, descriptor):拦截Object.defineProperty()方法
  4. 优点
    1. 可以对目标对象的操作进行拦截和修改,实现对目标对象的动态控制和增强
    2. 可以用于实现数据绑定,数据校验,日志记录功能
  5. 缺点:
    1. 兼容性较差,不支持IE浏览器
    2. 由于proxy可以拦截目标对象的所有操作,使用不当可能导致性能问题或安全问题

十八 generator 实现(8.21)

  1. 生成器(Generator)是一种特殊的函数,可以通过function*语法来定义。Generator函数可以通过yield关键字来暂停执行,并返回一个值给调用者。调用者可以通过生成器的next()方法来恢复生成器的执行,并获取生成器返回的值

  2. 简单实例

    function* myGenerator() {
        yield: 1;
        yield: 2;
        yield: 3;
    }
    
    // 创建生成器对象
    
    const generator = myGenerator()
    
    // 调用生成器的next()方法来获取生成器返回的值
    
    console.log(generator.next()); // { value: 1, done: false }
    console.log(generator.next()); // { value: 2, done: false }
    console.log(generator.next()); // { value: 3, done: false }
    console.log(generator.next()); // { value: undefined, done: true }

十九 事件模型(8.22) 

  1. 三个阶段
    1. 捕获阶段:事件从最外层的祖先元素向目标元素进行传播
    2. 目标阶段:事件到达目标元素的阶段
    3. 冒泡阶段:事件从目标元素开始向最外层的祖先元素进行传播的阶段
  2. 冒泡事件:当你使用事件冒泡时,子元素先触发,祖先元素后触发
  3. 捕获事件:当你使用事件捕获时,父元素先触发,子元素后触发
  4. 阻止冒泡: stopPropagation(),IE设置cancelBubble = true
  5. 阻止捕获:IE设置widow.event.returnValue = false,其他preeventDefault()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值