深入理解JS | 青训营笔记

76 阅读5分钟

深入理解JS

JS的基本概念

JavaScript(简称JS)是一种高级的、解释型的、动态类型的编程语言。它可以用于开发客户端脚本、服务器端脚本和桌面应用程序等。JS由ECMAScript标准定义,并且在不同的浏览器和操作系统中具有相同的语法和行为。

JS的数据类型

JS的数据类型包括:数字(Number)、字符串(String)、布尔值(Boolean)、对象(Object)、数组(Array)、null和undefined。

  • 数字:表示整数或浮点数,例如:123、3.14、-56789。
  • 字符串:表示文本数据,以双引号或单引号包裹,例如:'Hello, world!'。
  • 布尔值:表示true或false。
  • 对象:表示一组属性和方法的集合,以大括号{}包裹,例如:{name: 'Tom', age: 18}、[1, 2, 3, 4, 5]。
  • 数组:表示一组有序的元素集合,以方括号[]包裹,例如:[1, 2, 3, 4, 5]。
  • null和undefined:表示一个变量没有被初始化或者没有赋值,null表示空指针,undefined表示未定义的变量。

JS的变量提升

JS中的变量提升是指在代码执行前将变量声明提升到作用域的顶部。这意味着在声明变量之前使用该变量是非法的,但是一旦变量被提升到顶部,就可以正常使用它了。

例如:

console.log(x); // undefined
var x = 1;

在上述代码中,变量x在声明之前被使用了,因此会输出undefined。但是一旦变量x被提升到顶部,就可以正常使用了。

JS的作用域

JS中的作用域指的是变量的可访问性范围。JS中有四种不同的作用域类型:全局作用域、函数作用域、块级作用域和闭包作用域。

  • 全局作用域:在函数外部声明的变量具有全局作用域。它们可以在任何地方被访问和修改。
  • 函数作用域:在函数内部声明的变量具有函数作用域。它们只能在函数内部被访问和修改。
  • 块级作用域:在花括号({})内部声明的变量具有块级作用域。它们只能在花括号内部被访问和修改。
  • 闭包作用域:在一个函数内部创建另一个函数并返回它时,内部函数就会拥有自己的作用域。这个内部函数被称为闭包函数。闭包函数可以访问其外部函数的变量,即使外部函数已经执行完毕并退出了作用域。

例如:

function outerFunction() {
  var x = 10;
  function innerFunction() {
    console.log(x); // undefined (未提升)
  }
  return innerFunction;
}
var closure = outerFunction(); // closure是一个闭包函数
closure(); // 输出10 (已提升)

在上述代码中,innerFunction是一个闭包函数,它可以访问outerFunction中的变量x。当closure被赋值给一个变量时,x已经被提升到了作用域顶部,因此在closure调用时可以直接输出10。

JS的闭包

闭包是指一个函数能够访问并操作其创建时所在的词法环境(即封闭作用域)中的变量的能力。通过创建一个函数并将其返回,我们可以将一个私有变量封装在一个安全的位置中,从而实现数据的隐藏和保护。闭包还可以用于实现模块化编程和事件驱动编程等高级技术。

例如:

function createCounter() {
  var count = 0;
  function inc() {
    count++;
  }
  return inc;
}
var counter = createCounter(); // counter是一个闭包函数,可以访问createCounter中的变量count
counter(); // count从0开始自增1次,输出1;再次调用counter(),输出2;再次调用counter(),输出3; ...

JS的垃圾回收

JS中的垃圾回收是指自动管理内存的过程。当一个变量不再被引用时,它所占用的内存就会被标记为垃圾,等待垃圾回收器来释放它。

JS中的垃圾回收主要有两种方式:标记-清除和复制-粘贴。

  • 标记-清除:标记所有被引用的对象,然后清除所有未被标记的对象。这种方法比较高效,但可能会产生内存碎片。
  • 复制-粘贴:将内存分为两个相等的部分,每次只使用其中一个部分,当这个部分用尽时,将存活的对象复制到另一个部分中。这种方法可以解决内存碎片的问题,但会增加内存的使用率。

现代的JS引擎通常采用复制-粘贴的方式进行垃圾回收,以保证内存的连续性和稳定性。但是在一些特殊情况下,如使用闭包或循环引用等,仍然可能出现内存泄漏的情况。因此,在开发过程中需要注意内存管理的问题,避免出现内存泄漏或性能问题。

JS的总结思考

深入理解JS需要掌握其基本概念、语法和特性,并且需要了解其与其他编程语言的区别和联系。在实际开发中,需要结合具体的应用场景和需求,选择合适的技术和工具来进行开发和调试。同时,还需要关注JS的最新动态和发展,不断学习和更新自己的知识储备。