• JavaScript知识系列(2)每天10个小知识点



    👍 点赞,你的认可是我创作的动力!

    ⭐️ 收藏,你的青睐是我努力的方向!

    ✏️ 评论,你的意见是我进步的财富!


    系列文章目录

    JavaScript知识系列(1)每天10个小知识点

    知识点

    11. 如果 new 一个箭头函数的会怎么样

    在 JavaScript 中,如果您尝试使用 new 关键字来实例化(创建对象)一个箭头函数,会导致运行时错误。箭头函数与普通函数(使用 function 关键字声明的函数)有很重要的区别,其中之一就是箭头函数没有自己的 this 绑定和 prototype 属性。因此,它们不适合用作构造函数。

    试图使用 new 实例化箭头函数会导致 TypeError 错误。例如:

    const ArrowFunction = () => {
      this.name = 'John';
    };
    
    // 尝试使用 new 关键字实例化箭头函数
    const instance = new ArrowFunction(); // TypeError: ArrowFunction is not a constructor
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在上述示例中,new ArrowFunction() 会引发 TypeError 错误,因为箭头函数没有构造函数的功能,不能被用作类似构造函数的方式。

    要创建可以实例化的对象,您应该使用普通的函数(使用 function 关键字声明的函数),这些函数可以作为构造函数使用,并使用 new 关键字来创建新的对象实例。例如:

    function RegularFunction() {
      this.name = 'John';
    }
    
    const instance = new RegularFunction();
    console.log(instance.name); // "John"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    总之,箭头函数不适合用作构造函数,因此不应该使用 new 关键字来实例化它们。只有使用 function 关键字声明的函数才能被安全地用于实例化对象

    12. 箭头函数的 this 指向哪⾥?

    箭头函数的 this 指向的是其定义时所在的词法作用域(也称为外部作用域),而不是调用时的对象。这是箭头函数与普通函数(使用 function 关键字声明的函数)之间的主要区别之一。

    具体来说,箭头函数的 this 不会根据函数的调用方式而变化,而是在定义箭头函数时所在的上下文中确定。这通常是非常有用的,因为它可以避免在回调函数等情况下出现 this 绑定问题。

    例如:

    const obj = {
      name: 'John',
      greet: function () {
        console.log('Hello, ' + this.name);
      },
      arrowGreet: () => {
        console.log('Hello, ' + this.name); // this 指向的是全局对象,而不是 obj
      }
    };
    
    obj.greet();        // "Hello, John",this 指向 obj
    obj.arrowGreet();   // "Hello, undefined",this 指向全局对象
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在上面的示例中,greet 方法使用普通函数声明,它的 this 指向了 obj,因此可以正确访问 obj 的属性。而 arrowGreet 方法使用箭头函数声明,它的 this 指向的是全局对象(在浏览器环境中通常是 window),因此无法正确访问 obj 的属性。

    总结:箭头函数的 this 是静态的,由定义时的词法作用域决定,而普通函数的 this 是动态的,根据函数的调用方式和上下文不同而变化。因此,当需要在函数内部使用当前对象的属性时,通常使用普通函数,而不是箭头函数。

    13. 扩展运算符的概念、作用、原理、特性、优点、缺点、区别、使用场景

    扩展运算符(Spread Operator)是JavaScript中的一种语法,用于将一个可迭代(可遍历)对象(如数组、字符串、对象字面量等)拆分成独立的元素或属性,并将它们应用到另一个目标对象中。扩展运算符使用三个连续的点号(...)表示。

    以下是有关扩展运算符的详细信息:

    概念

    • 扩展运算符是一种展开可迭代对象的语法,允许将它们的元素或属性解构到其他数据结构中。

    作用

    • 扩展运算符用于快速、方便地将多个元素或属性合并到一个新的数组、对象或其他可迭代对象中。

    原理

    • 扩展运算符遍历源对象的元素或属性,并将它们逐个复制到目标对象中。

    特性

    • 扩展运算符只复制可枚举属性。
    • 扩展运算符不会复制原型链上的属性。
    • 扩展运算符创建的是浅拷贝,即对象内部嵌套对象的引用仍然相同。
    • 扩展运算符可以用于数组、对象、字符串、函数参数等多种情况。

    优点

    • 提供了一种简洁的语法,用于合并和展开数据结构,使代码更清晰和可读。
    • 可以用于函数参数中,简化函数的参数传递。

    缺点

    • 创建的是浅拷贝,不适用于需要深拷贝的情况。
    • 在处理大型对象时可能会产生性能问题,因为它会复制整个对象。

    区别

    • 与剩余参数(Rest Parameters)不同,扩展运算符用于展开对象,而剩余参数用于接收多个参数并将它们收集到一个数组中。
    • 与展开操作符(Spread Operator)不同,扩展运算符主要用于拆分和合并可迭代对象的元素或属性,而展开操作符用于在数组字面量或函数调用中展开元素。

    使用场景

    • 合并数组:

      const arr1 = [1, 2, 3];
      const arr2 = [4, 5, 6];
      const mergedArray = [...arr1, ...arr2];
      
      
      • 1
      • 2
      • 3
      • 4
    • 复制数组或对象:

      const originalArray = [1, 2, 3];
      const copiedArray = [...originalArray];
      
      
      • 1
      • 2
      • 3
    • 合并对象:

      const obj1 = { a: 1, b: 2 };
      const obj2 = { b: 3, c: 4 };
      const mergedObject = { ...obj1, ...obj2 };
      
      
      • 1
      • 2
      • 3
      • 4
    • 传递参数给函数:

      function exampleFunction(a, b, c) {
        // ...
      }
      
      const args = [1, 2, 3];
      exampleFunction(...args);
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    扩展运算符是 JavaScript 中一个非常实用的功能,可以简化代码并提高可读性。但需要注意它的浅拷贝特性以及性能问题,确保在适当的情况下使用。

    14. Proxy的概念、作用、原理、特性、优点、缺点、区别、使用场景

    Proxy 是 ECMAScript 6(ES6)引入的一个新特性,它是一种用于自定义对象操作行为的机制。Proxy 可以拦截并修改对象的操作,比如属性访问、赋值、函数调用等。以下是有关 Proxy 的详细信息:

    概念

    • Proxy 是一种代理机制,允许您创建一个代理对象,该代理对象可以拦截并自定义目标对象上的操作。

    作用

    • Proxy 主要用于自定义对象的行为,使得可以拦截和修改对象上的操作,以实现更高级的操作控制和元编程。

    原理

    • Proxy 对象包装了目标对象,并通过捕获器(handler)来定义代理对象上的操作行为。捕获器是一个包含各种操作处理函数的对象,当尝试对代理对象进行操作时,捕获器中相应操作的处理函数将被调用。

    特性

    • 可以拦截目标对象的多种操作,如属性读写、属性检查、函数调用、迭代等。
    • 支持自定义操作的行为,可以实现属性验证、属性代理、数据响应等高级特性。

    优点

    • 可以在对象操作的不同阶段介入,实现更精确的控制和逻辑。
    • 支持创建可撤销的代理,允许取消代理的拦截效果。
    • 支持元编程,使得可以在运行时修改对象行为,实现更高级的抽象和功能。

    缺点

    • 使用 Proxy 可能会导致性能损失,因为它引入了额外的拦截逻辑。
    • Proxy 不是所有 JavaScript 运行环境都支持,需要考虑兼容性。

    区别

    • Proxy 与 Object.defineProperty:Proxy 提供了更广泛的拦截和自定义能力,而 Object.defineProperty 主要用于拦截对象属性的读写操作。
    • Proxy 与 Object.observe:Object.observe 用于监视对象的变化,而 Proxy 用于拦截和修改对象的操作行为。

    使用场景

    • 数据验证和响应:可以使用 Proxy 来验证对象属性的值,或者实现数据响应系统(比如 Vue.js 中的响应式数据)。
    • 属性代理:可以在访问对象属性时添加额外的逻辑,例如记录属性访问日志。
    • 拦截函数调用:可以拦截函数调用,并添加额外的逻辑或参数处理。
    • 数据缓存和懒加载:可以拦截属性访问,并根据需要加载或计算属性值。
    • 元编程和代理模式:可以创建自定义的代理对象,实现元编程、代理模式或其他高级设计模式。

    总之,Proxy 是一项强大的功能,用于自定义对象的行为,可以实现高级的编程控制和抽象。但需要注意性能问题,并确保在需要高级自定义行为时使用它。

    15. 常用的正则表达式有哪些?

    正则表达式是一种强大的文本匹配工具,用于在文本中查找、匹配和操作字符串模式。以下是一些常用的正则表达式示例,它们可以用于不同的文本匹配需求:

    1. 匹配邮箱地址

      /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/
      
      
      • 1
      • 2
    2. 匹配 URL

      /^(https?|ftp):\\/\\/[^\\s/$.?#].[^\\s]*$/
      
      
      • 1
      • 2
    3. 匹配日期(yyyy-mm-dd 格式)

      /^\\d{4}-\\d{2}-\\d{2}$/
      
      
      • 1
      • 2
    4. 匹配手机号码

      /^1[3456789]\\d{9}$/
      
      
      • 1
      • 2
    5. 匹配 IP 地址

      /^(\\d{1,3}\\.){3}\\d{1,3}$/
      
      
      • 1
      • 2
    6. 匹配 HTML 标签(提取 HTML 标签内容):

      /<[^>]+>/
      
      
      • 1
      • 2
    7. 匹配数字(整数或浮点数):

      /^-?\\d+(\\.\\d+)?$/
      
      
      • 1
      • 2
    8. 匹配用户名(包含字母、数字、下划线,长度为 4 到 16 个字符):

      /^[a-zA-Z0-9_]{4,16}$/
      
      
      • 1
      • 2
    9. 匹配密码(至少包含一个大写字母、一个小写字母、一个数字,长度为 8 到 20 个字符):

      /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,20}$/
      
      
      • 1
      • 2
    10. 匹配中文字符

      /[\\u4e00-\\u9fa5]/
      
      
      • 1
      • 2

    这些是一些常见的正则表达式示例,用于处理常见的文本匹配任务。请注意,正则表达式可以根据具体需求进行修改和定制,以满足不同的匹配要求。要在 JavaScript 中使用正则表达式,可以使用 RegExp 构造函数或直接使用正则字面量。

    16. JSON的概念、作用、原理、特性、优点、缺点、区别、使用场景

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在不同的系统之间传输和存储数据。以下是有关 JSON 的详细信息:

    概念

    • JSON 是一种文本格式,用于表示结构化数据。
    • 它是基于键值对的数据表示,支持嵌套和多种数据类型。

    作用

    • JSON 主要用于数据交换和存储,使不同系统之间能够轻松地共享数据。
    • JSON 可以被解析为对象,用于在编程中访问和操作数据。

    原理

    • JSON 使用文本表示数据,采用键值对的形式组织数据。
    • 基本数据类型包括字符串、数字、布尔、null,以及数组和对象作为复合类型。
    • JSON 的解析和序列化可以通过编程语言中的 JSON 解析器和序列化器来完成。

    特性

    • 轻量级:JSON 使用文本格式,相对较小,便于传输和存储。
    • 人类可读:JSON 数据格式对人类来说易于阅读和编写。
    • 平台无关:JSON 是一种独立于编程语言和平台的数据表示格式。

    优点

    • 简单性:JSON 的语法简单,易于理解和使用。
    • 易于解析:大多数编程语言都提供了 JSON 解析器,使得解析 JSON 数据变得简单。
    • 跨平台和跨语言:JSON 可以在不同的编程语言和平台之间轻松传递数据。

    缺点

    • 不支持注释:JSON 不支持注释,不适合用作配置文件。
    • 不适合二进制数据:JSON 是文本格式,不适合存储或传输二进制数据。
    • 不支持循环引用:JSON 不支持对象之间的循环引用。

    区别

    • JSON 与 XML:JSON 更轻量、更容易阅读和编写,而 XML 更适合描述文档结构。
    • JSON 与 YAML:YAML 也是一种轻量级数据交换格式,但它更关注可读性,而 JSON 更常用于机器间通信。

    使用场景

    • 数据交换:JSON 通常用于 Web 服务中的数据交换,包括 RESTful API。
    • 配置文件:JSON 可以用作配置文件,例如前端应用的配置文件。
    • 数据存储:某些 NoSQL 数据库使用 JSON 作为数据存储格式。
    • 日志记录:JSON 可以用于结构化日志记录。
    • 在前端和后端之间传递数据:前后端通信中常使用 JSON 来传递数据,例如 AJAX 请求和响应。

    总之,JSON 是一种简单、轻量级且通用的数据表示格式,广泛用于数据交换、配置文件和数据存储等多个领域。它的主要优点是简单性和跨平台兼容性。

    17. JavaScript 脚本延迟加载的方式有哪些?

    JavaScript 脚本延迟加载是一种优化网页性能的技术,它允许将 JavaScript 文件的下载和执行推迟到页面的其他内容已经加载完毕后再进行。这有助于提高网页的加载速度和用户体验。以下是几种常见的 JavaScript 脚本延迟加载方式:

    1. async 属性
      使用