JavaScript 就像网页的"魔法师",能让静态的网页变得生动有趣。它可以:
// 在网页中
console.log("Hello, World!"); // 在浏览器控制台看到输出
// 在 HTML 中
<script>
alert("欢迎来到我的网站!");
</script>
// var - 老式写法,不推荐
var name = "小明";
// let - 推荐用于会改变的变量
let age = 25;
age = 26; // 可以修改
// const - 推荐用于不会改变的变量
const PI = 3.14159;
// PI = 3.14; // 错误!不能修改
记忆技巧:
let
= “让我改变”const
= “constant(常量),不变”let message = "你好,世界!";
let name = '小红';
let template = `我的名字是 ${name}`; // 模板字符串,可以插入变量
// 常用方法
console.log(message.length); // 6 - 字符串长度
console.log(message.toUpperCase()); // 转大写
console.log(message.includes("世界")); // true - 是否包含某文字
let score = 95;
let price = 19.99;
let negative = -10;
// 常用操作
console.log(Math.max(10, 20, 5)); // 20 - 最大值
console.log(Math.round(19.99)); // 20 - 四舍五入
console.log(Math.random()); // 0-1之间的随机数
let isStudent = true;
let isWorking = false;
// 判断真假
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("")); // false - 空字符串是假
console.log(Boolean("hello")); // true - 有内容是真
let fruits = ["苹果", "香蕉", "橙子"];
let numbers = [1, 2, 3, 4, 5];
// 常用操作
console.log(fruits[0]); // "苹果" - 第一个元素(从0开始)
fruits.push("葡萄"); // 添加到末尾
fruits.pop(); // 删除最后一个
console.log(fruits.length); // 数组长度
let person = {
name: "小王",
age: 30,
city: "北京",
hobbies: ["读书", "游泳"]
};
// 访问属性
console.log(person.name); // "小王"
console.log(person["age"]); // 30
// 修改属性
person.age = 31;
person.job = "程序员"; // 添加新属性
let a = 10, b = 3;
console.log(a + b); // 13 - 加法
console.log(a - b); // 7 - 减法
console.log(a * b); // 30 - 乘法
console.log(a / b); // 3.333... - 除法
console.log(a % b); // 1 - 余数(取模)
// 自增自减
let count = 5;
count++; // count = count + 1,现在是6
count--; // count = count - 1,现在是5
let x = 5, y = "5";
console.log(x == y); // true - 相等(会转换类型)
console.log(x === y); // false - 严格相等(不转换类型)
console.log(x != y); // false - 不等
console.log(x !== y); // true - 严格不等
console.log(x > 3); // true - 大于
console.log(x <= 5); // true - 小于等于
重要提示: 推荐使用 ===
和 !==
,避免意外的类型转换!
let age = 20;
let hasLicense = true;
// && - 并且(都要为真)
if (age >= 18 && hasLicense) {
console.log("可以开车");
}
// || - 或者(任一为真即可)
if (age < 18 || !hasLicense) {
console.log("不能开车");
}
// ! - 非(取反)
console.log(!hasLicense); // false
let weather = "晴天";
if (weather === "晴天") {
console.log("出去玩!");
} else if (weather === "雨天") {
console.log("在家看书");
} else {
console.log("看情况再说");
}
// 简写形式(三元运算符)
let message = weather === "晴天" ? "出去玩!" : "在家待着";
let day = "周一";
switch (day) {
case "周一":
console.log("新的一周开始!");
break;
case "周五":
console.log("快到周末了!");
break;
case "周六":
case "周日":
console.log("休息日!");
break;
default:
console.log("普通的一天");
}
// 打印1到5
for (let i = 1; i <= 5; i++) {
console.log(`第 ${i} 次`);
}
// 遍历数组
let colors = ["红", "绿", "蓝"];
for (let i = 0; i < colors.length; i++) {
console.log(colors[i]);
}
let count = 1;
while (count <= 3) {
console.log(`计数:${count}`);
count++;
}
let fruits = ["苹果", "香蕉", "橙子"];
for (let fruit of fruits) {
console.log(`我喜欢${fruit}`);
}
函数就像"小工厂",输入原料,输出产品。
// 声明函数
function greet(name) {
return `你好,${name}!`;
}
// 调用函数
let message = greet("小明");
console.log(message); // "你好,小明!"
// 有默认值的函数
function introduce(name, age = 18) {
return `我是${name},今年${age}岁`;
}
console.log(introduce("小红")); // "我是小红,今年18岁"
console.log(introduce("小蓝", 25)); // "我是小蓝,今年25岁"
// 普通函数
function add(a, b) {
return a + b;
}
// 箭头函数(推荐)
const add = (a, b) => a + b;
// 更复杂的箭头函数
const calculateArea = (length, width) => {
const area = length * width;
return `面积是 ${area} 平方米`;
};
const numbers = [1, 2, 3, 4, 5];
// map - 转换每个元素
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter - 筛选元素
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4]
// reduce - 累计计算
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15
// 对象方法
const calculator = {
result: 0,
add(number) {
this.result += number;
return this; // 返回自己,支持链式调用
},
multiply(number) {
this.result *= number;
return this;
},
getResult() {
return this.result;
}
};
// 链式调用
const result = calculator.add(5).multiply(2).getResult();
console.log(result); // 10
// 对象解构
const person = { name: "小王", age: 30, city: "上海" };
const { name, age } = person; // 提取属性
console.log(name, age); // "小王" 30
// 对象展开
const updatedPerson = { ...person, age: 31, job: "工程师" };
console.log(updatedPerson); // { name: "小王", age: 31, city: "上海", job: "工程师" }
const fruits = ["苹果", "香蕉", "橙子"];
// 数组解构
const [first, second] = fruits;
console.log(first, second); // "苹果" "香蕉"
// 展开运算符
const moreFruits = [...fruits, "葡萄", "草莓"];
console.log(moreFruits); // ["苹果", "香蕉", "橙子", "葡萄", "草莓"]
// 查找元素
const numbers = [1, 2, 3, 4, 5];
const found = numbers.find(num => num > 3); // 4
const foundIndex = numbers.findIndex(num => num > 3); // 3
// 检查条件
const allPositive = numbers.every(num => num > 0); // true
const hasEven = numbers.some(num => num % 2 === 0); // true
// 全局作用域
let globalVar = "我是全局变量";
function outerFunction() {
// 函数作用域
let outerVar = "我是外部函数变量";
function innerFunction() {
// 内层函数可以访问外层变量
let innerVar = "我是内部函数变量";
console.log(globalVar); // 可以访问
console.log(outerVar); // 可以访问
console.log(innerVar); // 可以访问
}
innerFunction();
// console.log(innerVar); // 错误!无法访问内层变量
}
outerFunction();
// 闭包的经典例子:计数器
function createCounter() {
let count = 0; // 私有变量
return function() {
count++; // 记住外部的 count
return count;
};
}
const counter1 = createCounter();
const counter2 = createCounter();
console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter2()); // 1 - 独立的计数器
// 实用例子:创建配置函数
function createMultiplier(factor) {
return function(number) {
return number * factor;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
同步就像排队买票,一个一个来;异步就像网上订餐,下单后可以做其他事,餐做好了会通知你。
// 创建 Promise
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve("数据获取成功!");
} else {
reject("网络错误");
}
}, 2000);
});
};
// 使用 Promise
fetchData()
.then(data => {
console.log(data); // 成功时执行
})
.catch(error => {
console.log(error); // 失败时执行
});
// 使用 async/await(推荐)
async function getData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.log("出错了:", error);
}
}
getData();
// 并行执行多个异步操作
async function getAllData() {
try {
const [data1, data2, data3] = await Promise.all([
fetchData(),
fetchData(),
fetchData()
]);
console.log("所有数据:", data1, data2, data3);
} catch (error) {
console.log("有一个失败了:", error);
}
}
const name = "小明";
const age = 25;
// 老写法
const message1 = "我是" + name + ",今年" + age + "岁";
// 新写法(推荐)
const message2 = `我是${name},今年${age}岁`;
// 多行字符串
const html = `
欢迎 ${name}
年龄:${age}
`;
// 老写法
function greet(name, greeting) {
greeting = greeting || "你好";
return greeting + "," + name;
}
// 新写法
function greet(name, greeting = "你好") {
return `${greeting},${name}`;
}
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
introduce() {
return `我是${this.name},今年${this.age}岁`;
}
// 静态方法
static createBaby(name) {
return new Person(name, 0);
}
}
// 继承
class Student extends Person {
constructor(name, age, school) {
super(name, age); // 调用父类构造函数
this.school = school;
}
introduce() {
return super.introduce() + `,在${this.school}上学`;
}
}
const student = new Student("小红", 16, "实验中学");
console.log(student.introduce());
// math.js - 导出模块
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
// main.js - 导入模块
import multiply, { PI, add } from './math.js';
console.log(PI); // 3.14159
console.log(add(2, 3)); // 5
console.log(multiply(4, 5)); // 20
// 所有对象都有原型
function Person(name) {
this.name = name;
}
// 在原型上添加方法
Person.prototype.greet = function() {
return `你好,我是${this.name}`;
};
const person1 = new Person("小明");
const person2 = new Person("小红");
console.log(person1.greet()); // "你好,我是小明"
console.log(person2.greet()); // "你好,我是小红"
// 原型链
console.log(person1.__proto__ === Person.prototype); // true
// 防抖函数 - 避免频繁触发
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
// 使用防抖
const debouncedSearch = debounce((query) => {
console.log(`搜索:${query}`);
}, 500);
// 节流函数 - 限制执行频率
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 使用节流
const throttledScroll = throttle(() => {
console.log("滚动事件");
}, 1000);
// 自定义错误
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
// 带错误处理的函数
function validateAge(age) {
if (age < 0) {
throw new ValidationError("年龄不能为负数");
}
if (age > 150) {
throw new ValidationError("年龄不能超过150岁");
}
return true;
}
// 使用 try-catch
try {
validateAge(-5);
} catch (error) {
if (error instanceof ValidationError) {
console.log("输入错误:", error.message);
} else {
console.log("未知错误:", error);
}
}
// 深拷贝
function deepClone(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(item => deepClone(item));
if (typeof obj === "object") {
const clonedObj = {};
for (let key in obj) {
clonedObj[key] = deepClone(obj[key]);
}
return clonedObj;
}
}
// 数组去重
const uniqueArray = arr => [...new Set(arr)];
// 随机选择数组元素
const randomChoice = arr => arr[Math.floor(Math.random() * arr.length)];
// 延迟函数
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// 使用示例
async function example() {
console.log("开始");
await delay(2000);
console.log("2秒后执行");
}
让我们用学到的知识做一个简单的待办事项应用:
class TodoApp {
constructor() {
this.todos = [];
this.nextId = 1;
}
// 添加待办事项
addTodo(text) {
const todo = {
id: this.nextId++,
text: text,
completed: false,
createdAt: new Date()
};
this.todos.push(todo);
return todo;
}
// 切换完成状态
toggleTodo(id) {
const todo = this.todos.find(t => t.id === id);
if (todo) {
todo.completed = !todo.completed;
}
return todo;
}
// 删除待办事项
deleteTodo(id) {
this.todos = this.todos.filter(t => t.id !== id);
}
// 获取所有待办事项
getAllTodos() {
return this.todos;
}
// 获取未完成的待办事项
getActiveTodos() {
return this.todos.filter(t => !t.completed);
}
// 获取已完成的待办事项
getCompletedTodos() {
return this.todos.filter(t => t.completed);
}
// 清除所有已完成的待办事项
clearCompleted() {
this.todos = this.todos.filter(t => !t.completed);
}
}
// 使用待办事项应用
const app = new TodoApp();
app.addTodo("学习 JavaScript");
app.addTodo("做项目练习");
app.addTodo("写技术博客");
console.log("所有待办:", app.getAllTodos());
app.toggleTodo(1); // 完成第一个任务
console.log("未完成:", app.getActiveTodos());
console.log("已完成:", app.getCompletedTodos());
// 使用 console.log 调试
function problematicFunction(data) {
console.log("输入数据:", data);
const result = data.map(item => {
console.log("处理项目:", item);
return item * 2;
});
console.log("最终结果:", result);
return result;
}
// 使用 debugger 断点
function debugExample() {
let x = 10;
debugger; // 浏览器会在这里暂停
x = x * 2;
return x;
}
记住:JavaScript 的学习需要大量实践,不要只看不做! 每个概念都要亲自写代码验证,这样才能真正掌握。
祝你学习愉快!