JavaScript学习记录|豆包MarsCode AI刷题

36 阅读4分钟

JS基础概念

JavaScript(简称 JS)是广泛用于前端开发的脚本语言,它是动态类型、解释型语言,主要用于构建动态交互式的 Web 应用

基本特性

  • 脚本语言:嵌入 HTML 页面,运行在浏览器中。
  • 弱类型、动态语言:变量类型在运行时确定,可以随时更改。
  • 事件驱动:可以响应用户行为(如点击、鼠标移动)。
  • 跨平台:运行在任何支持 JavaScript 的环境,如浏览器、服务器。

数据类型

  • 基本数据类型

    • Number:数字类型。
    • String:字符串类型
    • Boolean:布尔值,true 或 false。
    • Undefined:未定义变量,值为 undefined。
    • null:表示空值。
    • Symbol:独一无二的值。
    • BigInt:处理大整数。
  • 引用数据类型

    • Object:对象,如 { name: "John" }。
    • Array:数组,如 [1, 2, 3]。
    • Function:函数。

基本数据类型与引用数据类型的区别:

const a = {
name:'sq'
}
const b = a
b.name = 'xxx'
console.log(a.name) // xxx

const str = 'xy'
const newStr = str;
newStr = '123'
console.log(str) //xy
conlole.log(newStr) // 123
  • 基础类型的特点是不可变,值是直接存储在变量中的。将一个基础类型的变量赋值给另一个变量时,实际上是拷贝了一个副本。因此,修改新变量不会影响原变量
  • 引用类型的值是保存在内存中的对象,当将一个引用类型变量赋值给另一个变量时,实际上是复制了其引用(内存地址),而不是数据本身。因此,修改新变量会影响原变量。

作用域

静态作用域,通过它就能够预测代码在执行过程中如何查找标识符。

JavaScript 采用词法作用域(静态作用域),也就是变量的作用域在代码书写时就已经决定了,而不是在代码执行时决定。在静态作用域中,可以预测代码执行时对标识符的查找顺序。简单来说,函数定义的位置决定了其作用域,而不是调用位置。

变量提升

  • var有变量提升

    console.log(a) //输出:undefined
    var a = 1;
    

    从上述代码我们可以知道,使用 var声明的变量会提升到函数或全局作用域的顶部,变量提升只是提升声明,不会提升赋值,因此提升后变量的值是 undefined。

  • let、const没有变量提升,提前访问会报错

    console.log(str) 
    console.log(some)
    const str = 'xxx'
    let some = 'abc'
    

    上述代码控制台会抛出两个ReferenceError错误,说明了let和从const没有变量提升,它们在块作用域内的暂时性死区内使用会报错。

  • function函数可以先调用在定义

    fn() //输出:函数被调用了
    function fn(){
      console.log("函数被调用了")
    }
    

    function声明会提升整个函数,可以在声明前调用。

  • 赋值给变量的函数无法提前调用,即函数表达式不会提升

    func() //ReferenceError
    const func = fucntion(){
      console.log("函数被调用了")
    }
    func() //输出:函数被调用了
    

总结

JavaScript 基础概念包括数据类型、作用域、变量提升等。数据类型分为基础类型(不可变)和引用类型(可变,存储为内存引用),赋值时基础类型拷贝值,引用类型共享内存地址。JavaScript 采用静态作用域(词法作用域),即作用域在编写时就已决定。变量提升使得 var 声明的变量在作用域顶部可见,而 letconst 具有暂时性死区,未初始化前无法访问。函数声明也提升,但函数表达式不会。这种机制增强了代码的灵活性与容错性,但需理解其运行方式,以避免潜在的作用域和赋值错误。

闭包

闭包是 JavaScript 中一个重要的概念,它指的是函数和其词法环境的组合
即使外部函数已经执行结束,闭包仍然可以访问外部函数作用域中的变量。

闭包的形成

闭包在以下情况下形成:

  1. 函数嵌套:一个函数内部定义另一个函数。
  2. 内部函数引用了外部函数的变量
  3. 外部函数返回了内部函数或将其传递到其他作用域
function outerFunction() {
  let count = 0; // 外部函数的局部变量

  function innerFunction() {
    count++; // 闭包访问并修改外部变量
    console.log(count);
  }

  return innerFunction; // 返回内部函数,形成闭包
}

const closure = outerFunction(); // outerFunction 执行后返回 innerFunction

closure(); // 输出 1
closure(); // 输出 2
closure(); // 输出 3

闭包的特点

  1. 可以访问外部函数作用域中的变量。
  2. 外部函数的局部变量会在闭包中被“记住”,不会被垃圾回收机制回收。
  3. 使用闭包可以实现数据的私有化。

应用场景

延迟应用、模块开发等。。。