什么是JavaScript
JavaScript是一种高级的、解释型的编程语言,最初设计用于为网页添加交互性。如今,JavaScript已经发展成为一种通用的编程语言,可以用于前端开发、后端开发、移动应用开发、桌面应用开发等多个领域。
JavaScript的特点
- 动态类型:变量的类型在运行时确定
- 解释型语言:无需编译,直接由JavaScript引擎解释执行
- 基于原型的面向对象:通过原型链实现继承
- 函数式编程支持:函数是一等公民,支持高阶函数
- 事件驱动:基于事件循环的异步编程模型
- 跨平台:可以在浏览器、服务器、移动设备等多种环境中运行
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的基础概念,包括:
- JavaScript概述:了解了JavaScript的特点、发展历史和应用领域
- 运行环境:学习了浏览器环境、Node.js环境等不同的JavaScript运行环境
- 核心概念:掌握了变量、数据类型、函数、对象等基本概念
- 执行机制:理解了执行上下文、作用域链、闭包、变量提升等重要概念
- 现代特性:学习了ES6+引入的模板字符串、解构赋值、展开运算符等新特性
这些基础概念是学习JavaScript的重要基石,为后续深入学习JavaScript的高级特性和实际应用打下了坚实的基础。
下一章我们将学习JavaScript的开发环境搭建和开发工具的使用。