JavaScript入门教程 - 从零开始学习JavaScript完整指南
JavaScript入门教程 - 从零开始学习JavaScript完整指南
目录
- JavaScript简介
- 环境搭建
- 第一个JavaScript程序
- JavaScript基础语法
- 数据类型和变量
- 运算符和表达式
- 控制流程
- 函数
- 对象和数组
- DOM操作
- 事件处理
- 异步编程
- ES6+新特性
- 实际项目案例
- 总结与进阶
1. JavaScript简介
JavaScript(简称JS)是一种高级的、解释型的编程语言。JavaScript是Web开发的核心技术之一,与HTML和CSS一起构成了现代Web开发的三大基础。
JavaScript的特点:
✅ 解释型语言:不需要编译,直接在浏览器中运行
✅ 动态类型:变量类型在运行时确定
✅ 面向对象:支持面向对象编程
✅ 函数式编程:支持函数式编程范式
✅ 跨平台:可以在浏览器、服务器、移动端运行
✅ 事件驱动:基于事件驱动的编程模型
1995年:Brendan Eich在Netscape公司创建了JavaScript
1997年:ECMAScript标准发布(ECMA-262)
2009年:Node.js发布,JavaScript可以运行在服务器端
2015年:ES6(ES2015)发布,带来重大更新
至今:每年发布新版本,持续演进
前端开发:网页交互、动态效果
后端开发:Node.js服务器开发
移动开发:React Native、Ionic等
桌面应用:Electron应用
游戏开发:Web游戏、HTML5游戏
物联网:嵌入式JavaScript
虽然名字相似,但JavaScript和Java是完全不同的语言:
| 特性 | JavaScript | Java |
|---|---|---|
| 类型 | 解释型 | 编译型 |
| 运行环境 | 浏览器/Node.js | JVM |
| 类型系统 | 动态类型 | 静态类型 |
| 用途 | Web开发 | 企业应用 |
2. 环境搭建
JavaScript最基础的运行环境就是浏览器,现代浏览器都内置了JavaScript引擎:
- Chrome/Edge:V8引擎
- Firefox:SpiderMonkey引擎
- Safari:JavaScriptCore引擎
浏览器开发者工具
按F12打开开发者工具,可以在Console中直接运行JavaScript代码。
代码编辑器
推荐使用以下编辑器:
- Visual Studio Code(推荐):免费,功能强大
- WebStorm:JetBrains出品,功能全面
- Sublime Text:轻量级编辑器
- Atom:GitHub出品的编辑器
创建一个index.html文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript入门</title>
</head>
<body>
<h1>Hello JavaScript</h1>
<script>
// JavaScript代码写在这里
console.log("Hello, World!");
</script>
</body>
</html>将JavaScript代码写在单独的.js文件中:
script.js:
console.log("这是外部JavaScript文件");index.html:
<!DOCTYPE html>
<html>
<head>
<title>JavaScript入门</title>
</head>
<body>
<script src="script.js"></script>
</body>
</html>如果想在命令行运行JavaScript,可以安装Node.js:
- 访问 https://nodejs.org/
- 下载并安装Node.js
- 验证安装:
node --version
npm --version- 运行JavaScript文件:
node script.js3. 第一个JavaScript程序
<!DOCTYPE html>
<html>
<head>
<title>第一个JavaScript程序</title>
</head>
<body>
<h1 id="greeting"></h1>
<script>
// 在控制台输出
console.log("Hello, World!");
// 修改页面内容
document.getElementById("greeting").textContent = "Hello, JavaScript!";
// 弹出提示框
alert("欢迎学习JavaScript!");
</script>
</body>
</html>JavaScript有多种输出方式:
// 1. console.log() - 控制台输出(最常用)
console.log("Hello, World!");
// 2. alert() - 弹出警告框
alert("Hello, World!");
// 3. document.write() - 写入HTML文档(不推荐)
document.write("Hello, World!");
// 4. innerHTML - 修改元素内容
document.getElementById("demo").innerHTML = "Hello, World!";
// 5. prompt() - 弹出输入框
let name = prompt("请输入您的名字:");
console.log("Hello, " + name + "!");// 单行注释
/*
* 多行注释
* 可以写多行
*/
/**
* 文档注释
* 用于生成API文档
* @param {string} name - 名字
* @returns {string} 问候语
*/
function greet(name) {
return "Hello, " + name + "!";
}4. JavaScript基础语法
// 语句:执行操作
let x = 10;
console.log(x);
// 表达式:产生值
10 + 20; // 表达式,值为30
x > 5; // 表达式,值为true或false标识符规则
- 必须以字母、下划线(_)或美元符号($)开头
- 后续可以是字母、数字、下划线或美元符号
- 区分大小写
- 不能使用关键字和保留字
// 合法的标识符
let userName = "Alice";
let _private = "private";
let $element = document.getElementById("demo");
let user123 = "user";
// 不合法的标识符
// let 123user = "user"; // 错误:不能以数字开头
// let user-name = "user"; // 错误:不能使用连字符JavaScript关键字
break, case, catch, class, const, continue, debugger,
default, delete, do, else, export, extends, finally,
for, function, if, import, in, instanceof, new, return,
super, switch, this, throw, try, typeof, var, void,
while, with, yield// 1. 使用分号(可选但推荐)
let x = 10;
let y = 20;
// 2. 使用缩进(2或4个空格)
function example() {
if (true) {
console.log("Hello");
}
}
// 3. 使用驼峰命名
let userName = "Alice";
let userAge = 25;
// 4. 常量使用大写
const MAX_SIZE = 100;
const API_URL = "https://api.example.com";5. 数据类型和变量
JavaScript有7种基本数据类型和1种引用类型:
基本类型(原始类型):
number- 数字string- 字符串boolean- 布尔值undefined- 未定义null- 空值symbol- 符号(ES6)bigint- 大整数(ES2020)
引用类型:
object- 对象(包括数组、函数等)
// 整数
let age = 25;
let count = -10;
// 浮点数
let price = 99.99;
let pi = 3.14159;
// 科学计数法
let bigNumber = 1e6; // 1000000
let smallNumber = 1e-3; // 0.001
// 特殊值
let infinity = Infinity;
let notANumber = NaN;
// 类型检查
console.log(typeof 42); // "number"
console.log(typeof 3.14); // "number"Number常用方法:
// 转换为整数
parseInt("123"); // 123
parseInt("123.45"); // 123
// 转换为浮点数
parseFloat("123.45"); // 123.45
// 保留小数位
let num = 3.14159;
num.toFixed(2); // "3.14"
num.toPrecision(3); // "3.14"
// 判断是否为NaN
isNaN(NaN); // true
isNaN(123); // false
// 判断是否为有限数
isFinite(123); // true
isFinite(Infinity); // false// 字符串声明
let str1 = "Hello";
let str2 = 'World';
let str3 = `Template`; // 模板字符串(ES6)
// 字符串连接
let greeting = "Hello" + " " + "World"; // "Hello World"
// 模板字符串(推荐)
let name = "Alice";
let message = `Hello, ${name}!`; // "Hello, Alice!"
// 多行字符串
let multiLine = `这是第一行
这是第二行
这是第三行`;
// 字符串长度
let str = "Hello";
console.log(str.length); // 5
// 访问字符
console.log(str[0]); // "H"
console.log(str.charAt(0)); // "H"String常用方法:
let str = "Hello World";
// 查找
str.indexOf("World"); // 6
str.includes("Hello"); // true
str.startsWith("Hello"); // true
str.endsWith("World"); // true
// 提取
str.substring(0, 5); // "Hello"
str.slice(0, 5); // "Hello"
str.substr(0, 5); // "Hello"(已废弃)
// 替换
str.replace("World", "JavaScript"); // "Hello JavaScript"
str.replaceAll("l", "L"); // "HeLLo WorLd"
// 大小写转换
str.toUpperCase(); // "HELLO WORLD"
str.toLowerCase(); // "hello world"
// 分割
str.split(" "); // ["Hello", "World"]
str.split(""); // ["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d"]
// 去除空白
" Hello ".trim(); // "Hello"
" Hello ".trimStart(); // "Hello "
" Hello ".trimEnd(); // " Hello"// 布尔值
let isTrue = true;
let isFalse = false;
// 布尔转换
Boolean(1); // true
Boolean(0); // false
Boolean(""); // false
Boolean("hello"); // true
Boolean(null); // false
Boolean(undefined); // false
// 逻辑运算
true && true; // true
true || false; // true
!true; // false// undefined - 变量声明但未赋值
let x;
console.log(x); // undefined
// null - 空值,需要显式赋值
let y = null;
console.log(y); // null
// 区别
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object"(历史遗留问题)
// 相等性
undefined == null; // true(宽松相等)
undefined === null; // false(严格相等)// 创建Symbol
let sym1 = Symbol();
let sym2 = Symbol("description");
// Symbol是唯一的
let sym3 = Symbol("test");
let sym4 = Symbol("test");
console.log(sym3 === sym4); // false
// 作为对象属性
let obj = {
[sym1]: "value1",
[sym2]: "value2"
};// 创建BigInt
let bigInt = 1234567890123456789012345678901234567890n;
let bigInt2 = BigInt("123456789012345678901234567890");
// 运算
let a = 10n;
let b = 20n;
console.log(a + b); // 30n
console.log(a * b); // 200nvar(不推荐)
// var是函数作用域
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10(可以访问)
}
// 变量提升
console.log(y); // undefined(不会报错)
var y = 20;let(推荐)
// let是块作用域
function example() {
if (true) {
let x = 10;
}
// console.log(x); // 错误:x未定义
}
// 不能重复声明
let z = 10;
// let z = 20; // 错误:不能重复声明
// 必须先声明后使用
// console.log(a); // 错误:Cannot access 'a' before initialization
let a = 10;const(推荐)
// const是块作用域,必须初始化
const PI = 3.14159;
// PI = 3.14; // 错误:不能重新赋值
// const对象可以修改属性
const person = {
name: "Alice",
age: 25
};
person.age = 26; // 可以
// person = {}; // 错误:不能重新赋值
// const数组可以修改元素
const arr = [1, 2, 3];
arr.push(4); // 可以
// arr = []; // 错误:不能重新赋值隐式转换
// 字符串连接
"Hello" + 123; // "Hello123"
"10" + 5; // "105"
// 数学运算
"10" - 5; // 5
"10" * 2; // 20
"10" / 2; // 5
// 布尔转换
if ("hello") { } // true
if (0) { } // false
if ("") { } // false显式转换
// 转换为字符串
String(123); // "123"
(123).toString(); // "123"
123 + ""; // "123"
// 转换为数字
Number("123"); // 123
parseInt("123"); // 123
parseFloat("123.45"); // 123.45
+"123"; // 123
// 转换为布尔值
Boolean(1); // true
Boolean(0); // false
!!1; // true
!!0; // falsetypeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object"(历史遗留问题)
typeof Symbol(); // "symbol"
typeof 123n; // "bigint"
typeof {}; // "object"
typeof []; // "object"
typeof function(){}; // "function"6. 运算符和表达式
let a = 10;
let b = 3;
a + b; // 13 加法
a - b; // 7 减法
a * b; // 30 乘法
a / b; // 3.333... 除法
a % b; // 1 取余
a ** b; // 1000 幂运算(ES2016)
// 自增自减
let x = 5;
x++; // x = 6(后置)
++x; // x = 7(前置)
x--; // x = 6(后置)
--x; // x = 5(前置)let x = 10;
x += 5; // x = x + 5, 结果:15
x -= 3; // x = x - 3, 结果:12
x *= 2; // x = x * 2, 结果:24
x /= 4; // x = x / 4, 结果:6
x %= 4; // x = x % 4, 结果:2
x **= 3; // x = x ** 3, 结果:8let a = 10;
let b = 20;
a == b; // false 相等(会类型转换)
a != b; // true 不等
a === b; // false 严格相等(不类型转换)
a !== b; // true 严格不等
a < b; // true 小于
a > b; // false 大于
a <= b; // true 小于等于
a >= b; // false 大于等于
// 注意:== 和 === 的区别
"5" == 5; // true(类型转换)
"5" === 5; // false(不类型转换,推荐使用)let x = true;
let y = false;
x && y; // false 逻辑与
x || y; // true 逻辑或
!x; // false 逻辑非
// 短路求值
true && console.log("会执行"); // 会执行
false && console.log("不会执行"); // 不会执行
true || console.log("不会执行"); // 不会执行
false || console.log("会执行"); // 会执行let age = 20;
let status = age >= 18 ? "成年人" : "未成年人";
console.log(status); // "成年人"
// 嵌套使用
let score = 85;
let grade = score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" : "D";
console.log(grade); // "B"// 逗号运算符
let x = (1, 2, 3); // x = 3
// void运算符
void console.log("Hello"); // 返回undefined
// in运算符(检查对象属性)
let obj = {name: "Alice"};
"name" in obj; // true
"age" in obj; // false
// instanceof运算符(检查类型)
[] instanceof Array; // true
[] instanceof Object; // true7. 控制流程
let age = 20;
if (age >= 18) {
console.log("成年人");
} else {
console.log("未成年人");
}
// 多条件
let score = 85;
if (score >= 90) {
console.log("优秀");
} else if (score >= 80) {
console.log("良好");
} else if (score >= 60) {
console.log("及格");
} else {
console.log("不及格");
}
// 单行写法
if (age >= 18) console.log("成年人");let day = 3;
let dayName;
switch (day) {
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
default:
dayName = "未知";
}
console.log(dayName); // "星期三"
// 多个case合并
let month = 2;
switch (month) {
case 12:
case 1:
case 2:
console.log("冬季");
break;
case 3:
case 4:
case 5:
console.log("春季");
break;
// ...
}// 传统for循环
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...in循环(遍历对象属性)
let obj = {a: 1, b: 2, c: 3};
for (let key in obj) {
console.log(key + ": " + obj[key]);
}
// 输出:
// a: 1
// b: 2
// c: 3
// for...of循环(遍历可迭代对象,ES6)
let arr = [1, 2, 3, 4, 5];
for (let value of arr) {
console.log(value); // 1, 2, 3, 4, 5
}
// 遍历字符串
for (let char of "Hello") {
console.log(char); // H, e, l, l, o
}// while循环
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
// do...while循环
let j = 0;
do {
console.log(j);
j++;
} while (j < 5);// break:跳出循环
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // 当i等于5时跳出循环
}
console.log(i); // 0, 1, 2, 3, 4
}
// continue:跳过本次循环
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 跳过偶数
}
console.log(i); // 1, 3, 5, 7, 9
}// 标签用于break和continue
outer: for (let i = 0; i < 3; i++) {
inner: for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
break outer; // 跳出外层循环
}
console.log(i, j);
}
}8. 函数
// 函数声明
function greet(name) {
return "Hello, " + name + "!";
}
console.log(greet("Alice")); // "Hello, Alice!"
// 带默认参数(ES6)
function greet2(name = "World") {
return "Hello, " + name + "!";
}
console.log(greet2()); // "Hello, World!"
console.log(greet2("Alice")); // "Hello, Alice!"// 函数表达式
const greet = function(name) {
return "Hello, " + name + "!";
};
// 立即执行函数(IIFE)
(function() {
console.log("立即执行");
})();
// 箭头函数(ES6)
const greet3 = (name) => {
return "Hello, " + name + "!";
};
// 箭头函数简化
const greet4 = name => "Hello, " + name + "!";
const add = (a, b) => a + b;// 多个参数
function add(a, b, c) {
return a + b + c;
}
// 参数不足时,未提供的参数为undefined
add(1, 2); // NaN(1 + 2 + undefined)
// 剩余参数(ES6)
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4, 5); // 15
// arguments对象(不推荐,使用剩余参数)
function oldSum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}// 有返回值
function add(a, b) {
return a + b;
}
// 无返回值(返回undefined)
function greet(name) {
console.log("Hello, " + name);
}
// 提前返回
function checkAge(age) {
if (age < 0) {
return "无效年龄";
}
if (age < 18) {
return "未成年人";
}
return "成年人";
}// 全局作用域
let globalVar = "global";
function example() {
// 函数作用域
let localVar = "local";
console.log(globalVar); // "global"
console.log(localVar); // "local"
}
// console.log(localVar); // 错误:localVar未定义
// 块作用域(let/const)
if (true) {
let blockVar = "block";
console.log(blockVar); // "block"
}
// console.log(blockVar); // 错误:blockVar未定义// 闭包:函数可以访问外部作用域的变量
function outer() {
let count = 0;
function inner() {
count++;
return count;
}
return inner;
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
// 实际应用:模块模式
const calculator = (function() {
let result = 0;
return {
add: function(x) {
result += x;
return result;
},
subtract: function(x) {
result -= x;
return result;
},
getResult: function() {
return result;
}
};
})();
calculator.add(10); // 10
calculator.subtract(3); // 7
console.log(calculator.getResult()); // 7// 函数作为参数
function operate(a, b, operation) {
return operation(a, b);
}
const add = (x, y) => x + y;
const multiply = (x, y) => x * y;
console.log(operate(5, 3, add)); // 8
console.log(operate(5, 3, multiply)); // 15
// 函数作为返回值
function createMultiplier(multiplier) {
return function(x) {
return x * multiplier;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15// 计算阶乘
function factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
// 斐波那契数列
function fibonacci(n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci(10)); // 559. 对象和数组
// 对象字面量
let person = {
name: "Alice",
age: 25,
email: "alice@example.com",
greet: function() {
return "Hello, I'm " + this.name;
}
};
// 访问属性
console.log(person.name); // "Alice"
console.log(person["age"]); // 25
// 修改属性
person.age = 26;
person["email"] = "newemail@example.com";
// 添加属性
person.city = "Beijing";
person["country"] = "China";
// 删除属性
delete person.email;
// 方法调用
console.log(person.greet()); // "Hello, I'm Alice"let obj = {
name: "Alice",
age: 25,
// 方法简写(ES6)
greet() {
return "Hello, " + this.name;
},
// 箭头函数(注意this)
greet2: () => {
// this指向全局对象,不是obj
return "Hello";
}
};
// 计算属性名(ES6)
let prop = "name";
let obj2 = {
[prop]: "Alice",
["age" + "Value"]: 25
};let person = {
name: "Alice",
age: 25,
city: "Beijing"
};
// for...in循环
for (let key in person) {
console.log(key + ": " + person[key]);
}
// Object.keys()
Object.keys(person).forEach(key => {
console.log(key + ": " + person[key]);
});
// Object.values()(ES2017)
Object.values(person).forEach(value => {
console.log(value);
});
// Object.entries()(ES2017)
Object.entries(person).forEach(([key, value]) => {
console.log(key + ": " + value);
});// 数组字面量
let fruits = ["apple", "banana", "orange"];
// 访问元素
console.log(fruits[0]); // "apple"
console.log(fruits.length); // 3
// 修改元素
fruits[0] = "grape";
// 添加元素
fruits.push("mango"); // 末尾添加
fruits.unshift("kiwi"); // 开头添加
// 删除元素
fruits.pop(); // 删除末尾元素
fruits.shift(); // 删除开头元素
// 数组遍历
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// for...of循环
for (let fruit of fruits) {
console.log(fruit);
}
// forEach方法
fruits.forEach(fruit => {
console.log(fruit);
});let numbers = [1, 2, 3, 4, 5];
// map:映射
let doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter:过滤
let evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]
// reduce:归约
let sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15
// find:查找
let found = numbers.find(n => n > 3);
console.log(found); // 4
// findIndex:查找索引
let index = numbers.findIndex(n => n > 3);
console.log(index); // 3
// some:是否有元素满足条件
let hasEven = numbers.some(n => n % 2 === 0);
console.log(hasEven); // true
// every:是否所有元素都满足条件
let allPositive = numbers.every(n => n > 0);
console.log(allPositive); // true
// includes:是否包含元素
console.log(numbers.includes(3)); // true
// indexOf:查找索引
console.log(numbers.indexOf(3)); // 2
// slice:切片(不修改原数组)
let sliced = numbers.slice(1, 3);
console.log(sliced); // [2, 3]
// splice:修改数组
numbers.splice(1, 2, 10, 20); // 从索引1开始删除2个元素,插入10和20
console.log(numbers); // [1, 10, 20, 4, 5]
// sort:排序(修改原数组)
let unsorted = [3, 1, 4, 1, 5];
unsorted.sort((a, b) => a - b);
console.log(unsorted); // [1, 1, 3, 4, 5]
// reverse:反转(修改原数组)
let arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1]
// concat:连接数组(不修改原数组)
let arr1 = [1, 2];
let arr2 = [3, 4];
let combined = arr1.concat(arr2);
console.log(combined); // [1, 2, 3, 4]
// join:连接为字符串
let words = ["Hello", "World"];
console.log(words.join(" ")); // "Hello World"// 二维数组
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log(matrix[0][0]); // 1
console.log(matrix[1][2]); // 6
// 遍历二维数组
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
console.log(matrix[i][j]);
}
}10. DOM操作
DOM(Document Object Model)是HTML文档的对象模型,JavaScript可以通过DOM操作HTML元素。
// 根据ID选择
let element = document.getElementById("myId");
// 根据类名选择(返回NodeList)
let elements = document.getElementsByClassName("myClass");
// 根据标签名选择(返回NodeList)
let divs = document.getElementsByTagName("div");
// 根据选择器选择单个元素
let element2 = document.querySelector("#myId");
let element3 = document.querySelector(".myClass");
// 根据选择器选择多个元素(返回NodeList)
let elements2 = document.querySelectorAll(".myClass");// 修改文本内容
element.textContent = "新文本";
element.innerText = "新文本";
// 修改HTML内容
element.innerHTML = "<strong>新HTML</strong>";
// 修改属性
element.setAttribute("class", "newClass");
element.className = "newClass";
element.id = "newId";
// 修改样式
element.style.color = "red";
element.style.backgroundColor = "blue";
element.style.fontSize = "20px";// 创建元素
let newDiv = document.createElement("div");
newDiv.textContent = "新元素";
// 添加到页面
let parent = document.getElementById("parent");
parent.appendChild(newDiv);
// 插入到指定位置
let reference = document.getElementById("reference");
parent.insertBefore(newDiv, reference);
// 替换元素
parent.replaceChild(newDiv, reference);
// 删除元素
parent.removeChild(newDiv);<!DOCTYPE html>
<html>
<head>
<title>DOM操作示例</title>
</head>
<body>
<div id="container">
<h1 id="title">标题</h1>
<button id="btn">点击我</button>
<ul id="list"></ul>
</div>
<script>
// 获取元素
const title = document.getElementById("title");
const btn = document.getElementById("btn");
const list = document.getElementById("list");
// 修改标题
title.textContent = "新的标题";
title.style.color = "blue";
// 添加列表项
const items = ["项目1", "项目2", "项目3"];
items.forEach(item => {
const li = document.createElement("li");
li.textContent = item;
list.appendChild(li);
});
// 按钮点击事件
btn.addEventListener("click", function() {
const newItem = document.createElement("li");
newItem.textContent = "新项目";
list.appendChild(newItem);
});
</script>
</body>
</html>11. 事件处理
// 方式1:HTML属性(不推荐)
// <button onclick="handleClick()">点击</button>
// 方式2:DOM属性
let btn = document.getElementById("btn");
btn.onclick = function() {
console.log("按钮被点击");
};
// 方式3:addEventListener(推荐)
btn.addEventListener("click", function() {
console.log("按钮被点击");
});
// 移除事件监听器
function handleClick() {
console.log("点击");
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick);// 鼠标事件
element.addEventListener("click", handler); // 点击
element.addEventListener("dblclick", handler); // 双击
element.addEventListener("mousedown", handler); // 鼠标按下
element.addEventListener("mouseup", handler); // 鼠标释放
element.addEventListener("mousemove", handler); // 鼠标移动
element.addEventListener("mouseenter", handler); // 鼠标进入
element.addEventListener("mouseleave", handler); // 鼠标离开
// 键盘事件
element.addEventListener("keydown", handler); // 按键按下
element.addEventListener("keyup", handler); // 按键释放
element.addEventListener("keypress", handler); // 按键按下(已废弃)
// 表单事件
element.addEventListener("submit", handler); // 提交
element.addEventListener("change", handler); // 改变
element.addEventListener("input", handler); // 输入
element.addEventListener("focus", handler); // 获得焦点
element.addEventListener("blur", handler); // 失去焦点
// 窗口事件
window.addEventListener("load", handler); // 页面加载完成
window.addEventListener("resize", handler); // 窗口大小改变
window.addEventListener("scroll", handler); // 滚动element.addEventListener("click", function(event) {
// 事件类型
console.log(event.type); // "click"
// 目标元素
console.log(event.target); // 触发事件的元素
// 当前元素
console.log(event.currentTarget); // 绑定事件的元素
// 鼠标位置
console.log(event.clientX, event.clientY); // 相对于视口
console.log(event.pageX, event.pageY); // 相对于页面
// 键盘事件
console.log(event.key); // 按键
console.log(event.code); // 按键代码
// 阻止默认行为
event.preventDefault();
// 阻止事件冒泡
event.stopPropagation();
});// 事件委托:将事件监听器添加到父元素
let list = document.getElementById("list");
list.addEventListener("click", function(event) {
// 检查点击的是否是li元素
if (event.target.tagName === "LI") {
console.log("点击了:", event.target.textContent);
}
});
// 动态添加的元素也会响应事件
function addItem(text) {
const li = document.createElement("li");
li.textContent = text;
list.appendChild(li);
}
addItem("新项目"); // 点击也会触发事件12. 异步编程
// 回调函数
function fetchData(callback) {
setTimeout(() => {
callback("数据获取成功");
}, 1000);
}
fetchData(function(data) {
console.log(data);
});
// 回调地狱
fetchData(function(data1) {
processData(data1, function(data2) {
saveData(data2, function(result) {
console.log(result);
});
});
});// 创建Promise
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("操作成功");
} else {
reject("操作失败");
}
}, 1000);
});
// 使用Promise
promise
.then(result => {
console.log(result);
return "下一步";
})
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
})
.finally(() => {
console.log("完成");
});
// Promise.all:等待所有Promise完成
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log("全部完成", results);
})
.catch(error => {
console.error("有失败", error);
});
// Promise.race:返回第一个完成的Promise
Promise.race([promise1, promise2])
.then(result => {
console.log("第一个完成", result);
});// async函数返回Promise
async function fetchData() {
return "数据";
}
// await等待Promise完成
async function processData() {
try {
const data = await fetchData();
console.log(data);
return "处理完成";
} catch (error) {
console.error(error);
}
}
// 并行执行
async function fetchMultiple() {
const [data1, data2, data3] = await Promise.all([
fetchData1(),
fetchData2(),
fetchData3()
]);
return {data1, data2, data3};
}// GET请求
fetch("https://api.example.com/data")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// POST请求
fetch("https://api.example.com/data", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({name: "Alice", age: 25})
})
.then(response => response.json())
.then(data => console.log(data));
// 使用async/await
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
return data;
} catch (error) {
console.error(error);
}
}13. ES6+新特性
// let:块作用域
if (true) {
let x = 10;
}
// console.log(x); // 错误
// const:常量
const PI = 3.14159;
// PI = 3.14; // 错误// 传统函数
function add(a, b) {
return a + b;
}
// 箭头函数
const add = (a, b) => a + b;
// this绑定
let obj = {
name: "Alice",
greet: function() {
setTimeout(() => {
console.log("Hello, " + this.name);
}, 1000);
}
};// 数组解构
let [a, b, c] = [1, 2, 3];
let [x, , z] = [1, 2, 3]; // x=1, z=3
let [first, ...rest] = [1, 2, 3, 4]; // first=1, rest=[2,3,4]
// 对象解构
let {name, age} = {name: "Alice", age: 25};
let {name: userName, age: userAge} = {name: "Alice", age: 25};
// 默认值
let {name = "Unknown", age = 0} = {};let name = "Alice";
let age = 25;
// 传统方式
let message = "Hello, " + name + ". You are " + age + " years old.";
// 模板字符串
let message2 = `Hello, ${name}. You are ${age} years old.`;
// 多行字符串
let multiLine = `
这是第一行
这是第二行
这是第三行
`;// 数组展开
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = [...arr1, ...arr2]; // [1,2,3,4,5,6]
// 对象展开
let obj1 = {a: 1, b: 2};
let obj2 = {c: 3, ...obj1}; // {c:3, a:1, b:2}
// 函数参数
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10// 类定义
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
// 静态方法
static create(name, age) {
return new Person(name, age);
}
}
// 继承
class Student extends Person {
constructor(name, age, school) {
super(name, age);
this.school = school;
}
study() {
return `${this.name} is studying`;
}
}// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export default function multiply(a, b) {
return a * b;
}
// main.js
import multiply, {add, subtract} from "./math.js";
console.log(add(5, 3)); // 8
console.log(multiply(5, 3)); // 1514. 实际项目案例
<!DOCTYPE html>
<html>
<head>
<title>待办事项</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; }
#todoInput { width: 70%; padding: 10px; }
button { padding: 10px 20px; }
ul { list-style: none; padding: 0; }
li { padding: 10px; margin: 5px 0; background: #f0f0f0; display: flex; justify-content: space-between; }
.completed { text-decoration: line-through; opacity: 0.5; }
</style>
</head>
<body>
<h1>待办事项</h1>
<input type="text" id="todoInput" placeholder="输入待办事项...">
<button onclick="addTodo()">添加</button>
<ul id="todoList"></ul>
<script>
let todos = [];
function addTodo() {
const input = document.getElementById("todoInput");
const text = input.value.trim();
if (text) {
todos.push({
id: Date.now(),
text: text,
completed: false
});
input.value = "";
renderTodos();
}
}
function toggleTodo(id) {
const todo = todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
renderTodos();
}
}
function deleteTodo(id) {
todos = todos.filter(t => t.id !== id);
renderTodos();
}
function renderTodos() {
const list = document.getElementById("todoList");
list.innerHTML = todos.map(todo => `
<li class="${todo.completed ? 'completed' : ''}">
<span onclick="toggleTodo(${todo.id})">${todo.text}</span>
<button onclick="deleteTodo(${todo.id})">删除</button>
</li>
`).join("");
}
// 回车添加
document.getElementById("todoInput").addEventListener("keypress", function(e) {
if (e.key === "Enter") {
addTodo();
}
});
</script>
</body>
</html><!DOCTYPE html>
<html>
<head>
<title>天气查询</title>
</head>
<body>
<h1>天气查询</h1>
<input type="text" id="cityInput" placeholder="输入城市名">
<button onclick="getWeather()">查询</button>
<div id="weatherInfo"></div>
<script>
async function getWeather() {
const city = document.getElementById("cityInput").value;
const infoDiv = document.getElementById("weatherInfo");
if (!city) {
infoDiv.textContent = "请输入城市名";
return;
}
try {
// 注意:这里需要使用真实的API
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`);
const data = await response.json();
infoDiv.innerHTML = `
<h2>${data.name}</h2>
<p>温度: ${(data.main.temp - 273.15).toFixed(1)}°C</p>
<p>天气: ${data.weather[0].description}</p>
`;
} catch (error) {
infoDiv.textContent = "查询失败,请稍后重试";
}
}
</script>
</body>
</html>15. 总结与进阶
通过本教程,你已经掌握了:
- ✅ JavaScript基础语法
- ✅ 数据类型和变量
- ✅ 控制流程
- ✅ 函数编程
- ✅ 对象和数组操作
- ✅ DOM操作
- ✅ 事件处理
- ✅ 异步编程
- ✅ ES6+新特性
框架学习
- React
- Vue.js
- Angular
Node.js后端开发
- Express.js
- Koa.js
- Nest.js
工具和构建
- Webpack
- Vite
- Babel
测试
- Jest
- Mocha
- Jasmine
TypeScript
- 类型系统
- 接口和类
- 泛型
代码规范:使用ESLint等工具
模块化:合理组织代码结构
错误处理:完善的错误处理机制
性能优化:注意性能问题
安全性:防止XSS、CSRF等攻击
- MDN Web Docs:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
- JavaScript.info:https://zh.javascript.info/
- ES6入门教程:https://es6.ruanyifeng.com/
- LeetCode:算法练习
- GitHub:开源项目学习
结语
JavaScript是一门功能强大、应用广泛的编程语言。通过本教程的学习,相信你已经掌握了JavaScript的核心知识。
记住:
- 多实践:理论结合实践,多写代码
- 多思考:理解原理,不要死记硬背
- 多学习:关注新技术,持续学习
- 多交流:参与社区,分享经验
祝你学习愉快,编程顺利! 🚀
本教程由Java突击队学习社区编写,如有问题欢迎反馈。