什么是JavaScript

JavaScript是一种高级的、解释型的编程语言,最初设计用于为网页添加交互性。如今,JavaScript已经发展成为一种通用的编程语言,可以用于前端开发、后端开发、移动应用开发、桌面应用开发等多个领域。

JavaScript的特点

  1. 动态类型:变量的类型在运行时确定
  2. 解释型语言:无需编译,直接由JavaScript引擎解释执行
  3. 基于原型的面向对象:通过原型链实现继承
  4. 函数式编程支持:函数是一等公民,支持高阶函数
  5. 事件驱动:基于事件循环的异步编程模型
  6. 跨平台:可以在浏览器、服务器、移动设备等多种环境中运行

JavaScript的发展历史

  • 1995年:Brendan Eich在Netscape公司用10天时间创造了JavaScript
  • 1997年:ECMAScript标准发布(ES1)
  • 2009年:ES5发布,引入了严格模式
  • 2015年:ES6(ES2015)发布,引入了类、模块、箭头函数等重要特性
  • 2016年至今:每年发布一个新版本,持续演进

JavaScript运行环境

浏览器环境

浏览器是JavaScript最传统的运行环境,每个主流浏览器都内置了JavaScript引擎:

  • V8:Google Chrome、Microsoft Edge
  • SpiderMonkey:Mozilla Firefox
  • JavaScriptCore:Safari
  • Chakra:旧版Internet Explorer和Edge

Node.js环境

Node.js是基于Chrome V8引擎的JavaScript运行时,使JavaScript能够在服务器端运行:

// Node.js示例
const http = require('http');
const fs = require('fs');

const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('<h1>Hello from Node.js!</h1>');
});

server.listen(3000, () => {
  console.log('Server running on port 3000');
});

其他运行环境

  • Deno:现代的JavaScript/TypeScript运行时
  • Bun:快速的JavaScript运行时和包管理器
  • React Native:移动应用开发
  • Electron:桌面应用开发

JavaScript语言核心概念

1. 变量和数据类型

JavaScript有两类数据类型:

原始类型(Primitive Types)

// 数字类型
let age = 25;
let price = 99.99;
let infinity = Infinity;
let notANumber = NaN;

// 字符串类型
let name = "Alice";
let message = 'Hello World';
let template = `Hello, ${name}!`;

// 布尔类型
let isActive = true;
let isComplete = false;

// undefined类型
let undefinedVar;
console.log(undefinedVar); // undefined

// null类型
let nullVar = null;

// Symbol类型(ES6+)
let symbol1 = Symbol('description');
let symbol2 = Symbol('description');
console.log(symbol1 === symbol2); // false

// BigInt类型(ES2020+)
let bigNumber = 123456789012345678901234567890n;

引用类型(Reference Types)

// 对象类型
let person = {
  name: "Alice",
  age: 30,
  city: "New York"
};

// 数组类型
let numbers = [1, 2, 3, 4, 5];
let mixed = ["hello", 42, true, null];

// 函数类型
function greet(name) {
  return `Hello, ${name}!`;
}

// 日期类型
let now = new Date();
let specificDate = new Date('2024-01-01');

// 正则表达式类型
let pattern = /\d+/g;
let regex = new RegExp('\\w+', 'i');

2. 变量声明

JavaScript提供了三种变量声明方式:

// var声明(函数作用域,存在变量提升)
var oldStyle = "I'm old style";

// let声明(块作用域,ES6+)
let modernStyle = "I'm modern";

// const声明(块作用域,常量,ES6+)
const CONSTANT_VALUE = "I cannot be reassigned";

// 作用域示例
function scopeExample() {
  if (true) {
    var varVariable = "var is function scoped";
    let letVariable = "let is block scoped";
    const constVariable = "const is block scoped";
  }
  
  console.log(varVariable); // 可以访问
  // console.log(letVariable); // ReferenceError
  // console.log(constVariable); // ReferenceError
}

3. 函数

JavaScript中函数是一等公民,有多种定义方式:

// 函数声明
function add(a, b) {
  return a + b;
}

// 函数表达式
const multiply = function(a, b) {
  return a * b;
};

// 箭头函数(ES6+)
const divide = (a, b) => {
  return a / b;
};

// 简化的箭头函数
const square = x => x * x;
const greet = name => `Hello, ${name}!`;

// 高阶函数示例
function createMultiplier(factor) {
  return function(number) {
    return number * factor;
  };
}

const double = createMultiplier(2);
console.log(double(5)); // 10

// 立即执行函数表达式(IIFE)
(function() {
  console.log("I run immediately!");
})();

// 箭头函数的IIFE
(() => {
  console.log("Arrow IIFE!");
})();

4. 对象和数组

// 对象字面量
const user = {
  name: "Alice",
  age: 30,
  email: "alice@example.com",
  
  // 方法
  greet() {
    return `Hello, I'm ${this.name}`;
  },
  
  // 计算属性名(ES6+)
  ["user" + "Id"]: 12345
};

// 对象属性访问
console.log(user.name); // 点记法
console.log(user["email"]); // 括号记法
console.log(user.greet());

// 对象解构(ES6+)
const { name, age } = user;
const { email: userEmail } = user; // 重命名

// 数组操作
const fruits = ["apple", "banana", "orange"];

// 数组方法
fruits.push("grape"); // 添加到末尾
fruits.unshift("mango"); // 添加到开头
const lastFruit = fruits.pop(); // 移除并返回最后一个
const firstFruit = fruits.shift(); // 移除并返回第一个

// 数组高阶方法
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10]
const evens = numbers.filter(n => n % 2 === 0); // [2, 4]
const sum = numbers.reduce((acc, n) => acc + n, 0); // 15

// 数组解构
const [first, second, ...rest] = numbers;
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]

JavaScript的执行机制

1. 执行上下文

// 全局执行上下文
var globalVar = "I'm global";

function outerFunction() {
  // 函数执行上下文
  var outerVar = "I'm in outer function";
  
  function innerFunction() {
    // 嵌套函数执行上下文
    var innerVar = "I'm in inner function";
    console.log(globalVar); // 可以访问全局变量
    console.log(outerVar);  // 可以访问外层函数变量
    console.log(innerVar);  // 可以访问自己的变量
  }
  
  innerFunction();
}

outerFunction();

2. 作用域链

let globalScope = "global";

function level1() {
  let level1Scope = "level1";
  
  function level2() {
    let level2Scope = "level2";
    
    function level3() {
      let level3Scope = "level3";
      
      // 可以访问所有外层作用域的变量
      console.log(globalScope);  // "global"
      console.log(level1Scope);  // "level1"
      console.log(level2Scope);  // "level2"
      console.log(level3Scope);  // "level3"
    }
    
    level3();
  }
  
  level2();
}

level1();

3. 闭包

// 闭包示例1:数据私有化
function createCounter() {
  let count = 0;
  
  return {
    increment() {
      count++;
      return count;
    },
    decrement() {
      count--;
      return count;
    },
    getCount() {
      return count;
    }
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount()); // 2
// console.log(count); // ReferenceError: count is not defined

// 闭包示例2:函数工厂
function createGreeter(greeting) {
  return function(name) {
    return `${greeting}, ${name}!`;
  };
}

const sayHello = createGreeter("Hello");
const sayHi = createGreeter("Hi");

console.log(sayHello("Alice")); // "Hello, Alice!"
console.log(sayHi("Bob")); // "Hi, Bob!"

4. 变量提升(Hoisting)

// 变量提升示例
console.log(hoistedVar); // undefined(不是ReferenceError)
var hoistedVar = "I'm hoisted";

// 等价于:
// var hoistedVar;
// console.log(hoistedVar); // undefined
// hoistedVar = "I'm hoisted";

// 函数提升
console.log(hoistedFunction()); // "I'm hoisted!"

function hoistedFunction() {
  return "I'm hoisted!";
}

// let和const不会被提升到可用状态(暂时性死区)
// console.log(letVar); // ReferenceError
let letVar = "I'm let";

// console.log(constVar); // ReferenceError
const constVar = "I'm const";

现代JavaScript特性(ES6+)

1. 模板字符串

const name = "Alice";
const age = 30;

// 传统字符串拼接
const oldWay = "Hello, my name is " + name + " and I'm " + age + " years old.";

// 模板字符串
const newWay = `Hello, my name is ${name} and I'm ${age} years old.`;

// 多行字符串
const multiLine = `
  This is a
  multi-line
  string.
`;

// 标签模板
function highlight(strings, ...values) {
  return strings.reduce((result, string, i) => {
    const value = values[i] ? `<mark>${values[i]}</mark>` : '';
    return result + string + value;
  }, '');
}

const highlighted = highlight`Hello ${name}, you are ${age} years old!`;

2. 解构赋值

// 数组解构
const colors = ["red", "green", "blue", "yellow"];
const [primary, secondary, ...others] = colors;
console.log(primary); // "red"
console.log(secondary); // "green"
console.log(others); // ["blue", "yellow"]

// 对象解构
const person = {
  name: "Alice",
  age: 30,
  city: "New York",
  country: "USA"
};

const { name, age, ...address } = person;
console.log(name); // "Alice"
console.log(age); // 30
console.log(address); // { city: "New York", country: "USA" }

// 嵌套解构
const user = {
  id: 1,
  profile: {
    name: "Alice",
    contact: {
      email: "alice@example.com",
      phone: "123-456-7890"
    }
  }
};

const {
  profile: {
    name: userName,
    contact: { email }
  }
} = user;

console.log(userName); // "Alice"
console.log(email); // "alice@example.com"

3. 展开运算符和剩余参数

// 数组展开
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

// 对象展开
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }

// 剩余参数
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3, 4, 5)); // 15

// 函数参数展开
function greet(first, last) {
  return `Hello, ${first} ${last}!`;
}

const names = ["Alice", "Johnson"];
console.log(greet(...names)); // "Hello, Alice Johnson!"

4. 默认参数

// 默认参数值
function greet(name = "World", greeting = "Hello") {
  return `${greeting}, ${name}!`;
}

console.log(greet()); // "Hello, World!"
console.log(greet("Alice")); // "Hello, Alice!"
console.log(greet("Bob", "Hi")); // "Hi, Bob!"

// 默认参数可以是表达式
function createUser(name, id = Math.random()) {
  return { name, id };
}

// 默认参数可以引用前面的参数
function buildUrl(protocol = "https", domain, path = "/") {
  return `${protocol}://${domain}${path}`;
}

本章总结

本章介绍了JavaScript的基础概念,包括:

  1. JavaScript概述:了解了JavaScript的特点、发展历史和应用领域
  2. 运行环境:学习了浏览器环境、Node.js环境等不同的JavaScript运行环境
  3. 核心概念:掌握了变量、数据类型、函数、对象等基本概念
  4. 执行机制:理解了执行上下文、作用域链、闭包、变量提升等重要概念
  5. 现代特性:学习了ES6+引入的模板字符串、解构赋值、展开运算符等新特性

这些基础概念是学习JavaScript的重要基石,为后续深入学习JavaScript的高级特性和实际应用打下了坚实的基础。

下一章我们将学习JavaScript的开发环境搭建和开发工具的使用。