JavaScript 教程
JavaScript 是一种轻量级的解释型编程语言,主要用于网页开发,使网页具有交互性。本教程将从基础到高级全面介绍 JavaScript。
第一部分:JavaScript 基础
1. JavaScript 简介
JavaScript 是一种脚本语言,最初由 Netscape 的 Brendan Eich 在 1995 年开发。主要特点包括:
- 解释型语言(无需编译)
- 基于原型
- 动态类型
- 支持面向对象、命令式和函数式编程风格
2. 在 HTML 中使用 JavaScript
有三种方式在 HTML 中使用 JavaScript:
<!-- 1. 内联脚本 -->
<button onclick="alert('Hello!')">点击我</button>
<!-- 2. 内部脚本 -->
<script>
console.log("这是内部脚本");
</script>
<!-- 3. 外部脚本 -->
<script src="script.js"></script>
运行 HTML
3. 基本语法
变量声明
// ES5 方式
var name = "John";
// ES6 方式
let age = 30;
const PI = 3.14159;
数据类型
JavaScript 有 7 种基本数据类型和对象:
// 基本类型
let str = "Hello"; // 字符串
let num = 123; // 数字
let flag = true; // 布尔值
let nothing = null; // null
let notDefined; // undefined
let sym = Symbol('id'); // Symbol (ES6)
let bigInt = 123n; // BigInt (ES2020)
// 对象类型
let obj = { name: "John" };
let arr = [1, 2, 3];
let func = function() {};
运算符
// 算术运算符
let sum = 5 + 3; // 8
let mod = 10 % 3; // 1
// 比较运算符
console.log(5 == '5'); // true (值相等)
console.log(5 === '5'); // false (值和类型都相等)
// 逻辑运算符
let result = true && false; // false
result = true || false; // true
result = !true; // false
// 三元运算符
let message = (age >= 18) ? "成人" : "未成年";
控制结构
// if-else
if (age < 18) {
console.log("未成年");
} else if (age >= 18 && age < 65) {
console.log("成年人");
} else {
console.log("老年人");
}
// switch
switch (day) {
case 1:
console.log("星期一");
break;
case 2:
console.log("星期二");
break;
default:
console.log("其他");
}
// for 循环
for (let i = 0; i < 5; i++) {
console.log(i);
}
// while 循环
let j = 0;
while (j < 5) {
console.log(j);
j++;
}
// do-while
let k = 0;
do {
console.log(k);
k++;
} while (k < 5);
第二部分:JavaScript 核心概念
1. 函数
// 函数声明
function greet(name) {
return "Hello, " + name;
}
// 函数表达式
const greet = function(name) {
return "Hello, " + name;
};
// 箭头函数 (ES6)
const greet = (name) => `Hello, ${name}`;
// 默认参数
function greet(name = "Guest") {
return `Hello, ${name}`;
}
// 剩余参数
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
2. 对象
// 对象字面量
let person = {
name: "John",
age: 30,
greet: function() {
console.log("Hello!");
}
};
// 访问属性
console.log(person.name); // "John"
console.log(person["age"]); // 30
person.greet(); // "Hello!"
// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log("Hello, I'm " + this.name);
};
}
let john = new Person("John", 30);
3. 数组
let fruits = ["Apple", "Banana", "Orange"];
// 常用方法
fruits.push("Mango"); // 添加元素到末尾
fruits.pop(); // 移除最后一个元素
fruits.unshift("Grape"); // 添加元素到开头
fruits.shift(); // 移除第一个元素
// 遍历数组
fruits.forEach(function(fruit, index) {
console.log(index, fruit);
});
// map 方法
let lengths = fruits.map(fruit => fruit.length);
// filter 方法
let longFruits = fruits.filter(fruit => fruit.length > 5);
4. 作用域和闭包
// 作用域
let globalVar = "全局";
function scopeTest() {
let localVar = "局部";
console.log(globalVar); // 可以访问全局变量
console.log(localVar); // 可以访问局部变量
}
// console.log(localVar); // 报错,无法访问局部变量
// 闭包
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const counter = outer();
counter(); // 1
counter(); // 2
5. this 关键字
// 默认绑定
function showThis() {
console.log(this); // 浏览器中指向 window
}
// 隐式绑定
let obj = {
name: "John",
greet: function() {
console.log("Hello, " + this.name);
}
};
obj.greet(); // "Hello, John"
// 显式绑定
function greet() {
console.log("Hello, " + this.name);
}
greet.call(obj); // "Hello, John"
// new 绑定
function Person(name) {
this.name = name;
}
let john = new Person("John");
// 箭头函数中的 this
let arrowObj = {
name: "Arrow",
greet: () => {
console.log("Hello, " + this.name); // this 指向外层作用域
}
};
第三部分:JavaScript 高级特性
1. 原型和继承
// 原型
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + " makes a noise.");
};
let animal = new Animal("Animal");
animal.speak(); // "Animal makes a noise."
// 继承
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
console.log(this.name + " barks.");
};
let dog = new Dog("Rex");
dog.speak(); // "Rex barks."
2. ES6 类
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
speak() {
console.log(`${this.name} barks.`);
}
}
let dog = new Dog("Rex");
dog.speak(); // "Rex barks."
3. Promise 和异步编程
// Promise 基本用法
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
let success = true;
if (success) {
resolve("操作成功");
} else {
reject("操作失败");
}
}, 1000);
});
promise
.then(result => console.log(result))
.catch(error => console.error(error));
// async/await (ES2017)
async function fetchData() {
try {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
} catch (error) {
console.error("出错:", error);
}
}
4. 模块系统
// 导出模块 (module.js)
export const PI = 3.14159;
export function sum(a, b) {
return a + b;
}
export default class Calculator {
multiply(a, b) {
return a * b;
}
}
// 导入模块
import { PI, sum } from './module.js';
import Calculator from './module.js';
console.log(PI); // 3.14159
console.log(sum(2, 3)); // 5
let calc = new Calculator();
console.log(calc.multiply(4, 5)); // 20
5. 错误处理
// try-catch
try {
// 可能出错的代码
let result = riskyOperation();
console.log(result);
} catch (error) {
console.error("发生错误:", error.message);
} finally {
console.log("无论如何都会执行");
}
// 自定义错误
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
function validateInput(input) {
if (!input) {
throw new ValidationError("输入不能为空");
}
}
第四部分:浏览器中的 JavaScript
1. DOM 操作
// 选择元素
let header = document.getElementById("header");
let paragraphs = document.getElementsByClassName("text");
let buttons = document.querySelectorAll("button.primary");
// 修改内容
header.textContent = "新标题";
header.innerHTML = "<em>强调标题</em>";
// 样式操作
header.style.color = "blue";
header.classList.add("highlight");
// 事件处理
let button = document.querySelector("button");
button.addEventListener("click", function(event) {
console.log("按钮被点击了", event);
});
// 创建和添加元素
let newDiv = document.createElement("div");
newDiv.textContent = "新创建的元素";
document.body.appendChild(newDiv);
2. BOM (浏览器对象模型)
// window 对象
window.alert("这是一个警告");
let width = window.innerWidth;
// location 对象
console.log(location.href); // 当前URL
location.reload(); // 重新加载页面
location.href = "https://example.com"; // 跳转
// navigator 对象
console.log(navigator.userAgent); // 浏览器信息
// history 对象
history.back(); // 返回上一页
history.forward(); // 前进一页
// 定时器
let timeoutId = setTimeout(() => {
console.log("3秒后执行");
}, 3000);
let intervalId = setInterval(() => {
console.log("每隔1秒执行一次");
}, 1000);
// 清除定时器
clearTimeout(timeoutId);
clearInterval(intervalId);
3. 表单处理
let form = document.querySelector("form");
// 提交事件
form.addEventListener("submit", function(event) {
event.preventDefault(); // 阻止默认提交行为
let formData = new FormData(form);
let username = formData.get("username");
if (!username) {
alert("用户名不能为空");
return;
}
// 处理表单数据
console.log("表单数据:", Object.fromEntries(formData));
});
// 输入验证
let emailInput = document.getElementById("email");
emailInput.addEventListener("input", function() {
if (!this.value.includes("@")) {
this.setCustomValidity("请输入有效的电子邮件地址");
} else {
this.setCustomValidity("");
}
});
4. AJAX 和 Fetch API
// 传统 XMLHttpRequest
let xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data", true);
xhr.onload = function() {
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
} else {
console.error("请求失败:", xhr.statusText);
}
};
xhr.onerror = function() {
console.error("请求出错");
};
xhr.send();
// Fetch API
fetch("https://api.example.com/data")
.then(response => {
if (!response.ok) {
throw new Error("网络响应不正常");
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error("请求出错:", error));
// 使用 async/await 的 Fetch
async function getData() {
try {
let response = await fetch("https://api.example.com/data");
if (!response.ok) throw new Error("网络响应不正常");
let data = await response.json();
console.log(data);
} catch (error) {
console.error("请求出错:", error);
}
}
第五部分:现代 JavaScript 开发
1. ES6+ 新特性
// 解构赋值
let [a, b] = [1, 2];
let {name, age} = {name: "John", age: 30};
// 模板字符串
let greeting = `Hello, ${name}! You are ${age} years old.`;
// 展开运算符
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// 剩余参数
function logArgs(first, ...rest) {
console.log(first, rest);
}
// 对象属性简写
let name = "John";
let person = {name, age: 30};
// 可选链操作符 (ES2020)
let street = user?.address?.street;
// 空值合并运算符 (ES2020)
let value = input ?? "default";
2. 函数式编程
// 高阶函数
function multiplyBy(factor) {
return function(number) {
return number * factor;
};
}
let double = multiplyBy(2);
console.log(double(5)); // 10
// 纯函数
function add(a, b) {
return a + b; // 不依赖外部状态,没有副作用
}
// 不可变性
let numbers = [1, 2, 3];
let newNumbers = [...numbers, 4]; // 不修改原数组
// 函数组合
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
const add1 = x => x + 1;
const double = x => x * 2;
const addThenDouble = compose(double, add1);
console.log(addThenDouble(5)); // 12
3. TypeScript 简介
TypeScript 是 JavaScript 的超集,添加了静态类型系统。
// 基本类型
let name: string = "John";
let age: number = 30;
let isActive: boolean = true;
// 接口
interface Person {
name: string;
age: number;
greet?: () => void; // 可选方法
}
// 类
class Employee implements Person {
constructor(public name: string, public age: number) {}
greet() {
console.log(`Hello, I'm ${this.name}`);
}
}
// 泛型
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("hello");
4. 性能优化
// 1. 避免全局变量
(function() {
// 模块代码
})();
// 2. 事件委托
document.getElementById("list").addEventListener("click", function(e) {
if (e.target.tagName === "LI") {
console.log("列表项被点击:", e.target.textContent);
}
});
// 3. 节流和防抖
function debounce(func, delay) {
let timeoutId;
return function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, arguments), delay);
};
}
window.addEventListener("resize", debounce(function() {
console.log("窗口大小改变");
}, 200));
// 4. 使用 Web Workers 处理耗时任务
const worker = new Worker("worker.js");
worker.postMessage({data: "开始计算"});
worker.onmessage = function(e) {
console.log("收到结果:", e.data);
};
第六部分:常见 JavaScript 库和框架
1. jQuery
// 选择元素
let $divs = $("div.content");
// 修改内容
$("#header").text("新标题").addClass("highlight");
// 事件处理
$("button").on("click", function() {
$(this).fadeOut();
});
// AJAX
$.ajax({
url: "api/data",
method: "GET",
success: function(data) {
console.log(data);
},
error: function(error) {
console.error(error);
}
});
2. React 基础
jsx
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>当前计数: {count}</p>
<button onClick={() => setCount(count + 1)}>
增加
</button>
</div>
);
}
export default Counter;
3. Vue 基础
// Vue 3 示例
const { createApp, ref } = Vue;
const app = createApp({
setup() {
const count = ref(0);
function increment() {
count.value++;
}
return {
count,
increment
};
}
});
app.mount('#app');
4. Node.js 简介
// 简单的 HTTP 服务器
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000/');
});
第七部分:最佳实践和常见问题
1. 代码风格指南
- 使用一致的缩进(2或4个空格)
- 使用分号
- 使用 camelCase 命名变量和函数
- 使用 PascalCase 命名构造函数和类
- 使用全大写命名常量
- 使用描述性的名称
2. 常见错误和调试
// 1. 未定义变量
// console.log(undeclaredVar); // ReferenceError
// 2. 类型错误
let obj = null;
// console.log(obj.property); // TypeError
// 3. 使用 console.log 调试
console.log("当前值:", value);
// 4. 使用 debugger 语句
function problematicFunction() {
debugger; // 执行到这里会暂停
// 问题代码
}
3. 安全注意事项
- 避免使用 eval()
- 对用户输入进行验证和转义
- 使用 HTTPS 传输敏感数据
- 实现 CSRF 保护
- 使用 Content Security Policy (CSP)
4. 资源推荐
- MDN Web Docs (https://developer.mozilla.org)
- JavaScript.info (https://javascript.info)
- Eloquent JavaScript (https://eloquentjavascript.net)
- You Don't Know JS (书籍系列)
- ECMAScript 规范 (https://tc39.es/ecma262/)
结语
JavaScript 是一门功能强大且灵活的语言,从简单的网页交互到复杂的应用程序开发都能胜任。随着 ECMAScript 标准的不断更新和现代框架的出现,JavaScript 生态系统也在持续演进。掌握 JavaScript 不仅能让你构建交互式网页,还能开发跨平台的移动应用、桌面应用甚至服务器端应用。
学习 JavaScript 的最佳方式是不断实践,尝试构建各种项目,从简单的工具到复杂的应用程序。随着经验的积累,你会越来越熟悉这门语言的精妙之处。