JavaScript系列01-核心基础:变量、类型与作用域

本文介绍了JavaScript的核心基础知识,包括:

  1. JavaScript的发展历程,从简单脚本语言到现代web开发的支柱
  2. 三种变量声明方式(var、let、const)及其区别
  3. JavaScript的数据类型体系和类型转换机制
  4. 作用域概念和闭包原理
  5. 变量提升和暂时性死区的概念
  6. 通过实践案例展示了这些概念的应用

1、JavaScript的历史与发展

JavaScript诞生于1995年,由Brendan Eich在网景公司仅用10天时间创造出来。最初被命名为Mocha,后改名为LiveScript,最终被命名为JavaScript(这是一个市场营销决策,意在搭上当时流行的Java语言的顺风车)。

JavaScript的发展历程可以分为几个重要阶段:

  • 1997年:ECMAScript 1发布,JavaScript标准化
  • 2009年:ECMAScript 5发布,增加了严格模式等特性
  • 2015年:ECMAScript 6(ES6)发布,这是一次革命性的更新,引入了大量新特性
  • 2016年至今:每年一个小版本,持续增强语言特性

从一个简单的脚本语言发展为如今支撑整个互联网前端的主要编程语言,JavaScript已经远超其创造者的想象。

2、变量声明:var、let与const的区别

JavaScript中有三种声明变量的方式:var、let和const,它们有重要区别:

var声明

var name = '张三';

特点:

  • 函数作用域
  • 变量提升
  • 可以重复声明
  • 可以被修改

let声明

let age = 25;

特点:

  • 块级作用域
  • 不存在变量提升
  • 不能重复声明
  • 可以被修改

const声明

const PI = 3.14159;

特点:

  • 块级作用域
  • 不存在变量提升
  • 不能重复声明
  • 不能重新赋值(但对象的属性可以修改)

3、数据类型及类型转换

JavaScript有七种基本数据类型和一种复杂数据类型:

基本数据类型(原始类型)

  1. Number:数字(整数和浮点数)

    let count = 10;
    let price = 99.99;
    
  2. String:字符串

    let name = "李四";
    let greeting = '你好';
    
  3. Boolean:布尔值

    let isActive = true;
    let isCompleted = false;
    
  4. Undefined:未定义

    let something;  // 值为undefined
    
  5. Null:空值

    let empty = null;
    
  6. Symbol:(ES6新增)独一无二的值

    const sym = Symbol('描述');
    
  7. BigInt:(ES2020新增)大整数

    const bigNumber = 9007199254740991n;
    

复杂数据类型

  • Object:对象(包括数组、函数、日期等)
    let person = {name: '王五', age: 30};
    let numbers = [1, 2, 3, 4];
    

类型转换

JavaScript中的类型转换可以是隐式的或显式的:

隐式转换
let result = '3' + 2;  // 结果是字符串 "32"
let result2 = '3' - 2;  // 结果是数字 1
let result3 = '3' * '2';  // 结果是数字 6
显式转换
let num = Number('42');  // 将字符串转为数字
let str = String(42);    // 将数字转为字符串
let bool = Boolean(1);   // 将数字转为布尔值

4、作用域与闭包

作用域

作用域决定了变量的可见性和生命周期。JavaScript中有三种作用域:

  1. 全局作用域:在所有函数外部声明的变量

    let globalVar = '我是全局变量';
    
  2. 函数作用域:在函数内部声明的变量

    function test() {
      let localVar = '我是局部变量';
      console.log(localVar);  // 可以访问
    }
    // console.log(localVar);  // 报错:localVar未定义
    
  3. 块级作用域:在大括号内部使用let或const声明的变量

    if (true) {
      let blockVar = '我是块级变量';
      console.log(blockVar);  // 可以访问
    }
    // console.log(blockVar);  // 报错:blockVar未定义
    

闭包

闭包是指函数和它的词法环境的组合。简单说,闭包允许函数访问并操作函数外部的变量。

function createCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

闭包的关键在于内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。

5、变量提升与暂时性死区

变量提升

变量提升是指变量声明会被提升到当前作用域的顶部,但初始化不会被提升。

console.log(name); // undefined,而不是报错
var name = '张三';

// 上面的代码等同于:
var name;
console.log(name);  // undefined
name = '张三';

注意:只有使用var声明的变量会被提升。

函数提升

与变量类似,函数声明也会被提升:

sayHello(); // "你好,世界"

function sayHello() {
  console.log("你好,世界");
}

但是,函数表达式不会被提升:

sayHi(); // 报错:sayHi is not a function

var sayHi = function() {
  console.log("你好");
};

暂时性死区

使用letconst声明的变量也会被提升,但是不会被初始化,直到它们的声明语句被执行。这段区域称为"暂时性死区"。

console.log(age); // ReferenceError: age is not defined
let age = 25;

6、实践案例分析

下面通过一个实际案例来综合应用以上知识点:

案例:计数器应用

// 全局变量
let globalCounter = 0;

// 创建一个计数器工厂
function createCounter(initialValue) {
  // 使用参数默认值
  let count = initialValue || 0;
  
  // 返回一个包含多个方法的对象
  return {
    increment() {
      count++;
      return count;
    },
    decrement() {
      count--;
      return count;
    },
    getValue() {
      return count;
    },
    reset() {
      count = initialValue || 0;
      return count;
    }
  };
}

// 创建两个独立的计数器
const counterA = createCounter(10);
const counterB = createCounter(20);

console.log(counterA.getValue()); // 10
console.log(counterB.getValue()); // 20

counterA.increment();
counterA.increment();
console.log(counterA.getValue()); // 12

counterB.decrement();
console.log(counterB.getValue()); // 19

// 全局计数器
function incrementGlobal() {
  globalCounter++;
  console.log(`全局计数器:${globalCounter}`);
}

incrementGlobal(); // 全局计数器:1
incrementGlobal(); // 全局计数器:2

这个例子展示了:

  1. 闭包的使用(每个计数器维护自己的count变量)
  2. 不同作用域的变量(全局变量vs闭包中的变量)
  3. 对象方法与函数
  4. 默认参数值

作用域和闭包的实际应用

闭包广泛应用于:

  • 数据隐藏和封装
  • 模块模式
  • 函数工厂
  • 回调和事件处理

比如,以下是一个使用闭包实现私有变量的简单模块:

const bankAccount = (function() {
  // 私有变量
  let balance = 0;
  
  // 公共接口
  return {
    deposit(amount) {
      if (amount > 0) {
        balance += amount;
        return true;
      }
      return false;
    },
    withdraw(amount) {
      if (amount > 0 && balance >= amount) {
        balance -= amount;
        return true;
      }
      return false;
    },
    getBalance() {
      return balance;
    }
  };
})();

bankAccount.deposit(100);
console.log(bankAccount.getBalance()); // 100
bankAccount.withdraw(30);
console.log(bankAccount.getBalance()); // 70
console.log(bankAccount.balance); // undefined,无法直接访问私有变量

这种模式可以有效保护数据,只通过受控的接口进行操作。

总结

掌握这些基础知识对于理解JavaScript的行为和编写高质量的JavaScript代码至关重要。深入理解这些概念,将为学习更高级的JavaScript技术和框架打下坚实基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值