js学习手册

JavaScript 通俗易懂学习手册

目录

  1. 基础知识
  2. 变量和数据类型
  3. 运算符
  4. 控制流程
  5. 函数
  6. 对象和数组
  7. 作用域和闭包
  8. 异步编程
  9. ES6+ 新特性
  10. 高级概念

基础知识

JavaScript 是什么?

JavaScript 就像网页的"魔法师",能让静态的网页变得生动有趣。它可以:

  • 让按钮点击后有反应
  • 制作动画效果
  • 处理用户输入
  • 与服务器通信

如何运行 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(常量),不变”

数据类型

1. 字符串 (String) - 文字
let message = "你好,世界!";
let name = '小红';
let template = `我的名字是 ${name}`; // 模板字符串,可以插入变量

// 常用方法
console.log(message.length); // 6 - 字符串长度
console.log(message.toUpperCase()); // 转大写
console.log(message.includes("世界")); // true - 是否包含某文字
2. 数字 (Number) - 数值
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之间的随机数
3. 布尔值 (Boolean) - 真假
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 - 有内容是真
4. 数组 (Array) - 列表
let fruits = ["苹果", "香蕉", "橙子"];
let numbers = [1, 2, 3, 4, 5];

// 常用操作
console.log(fruits[0]); // "苹果" - 第一个元素(从0开始)
fruits.push("葡萄"); // 添加到末尾
fruits.pop(); // 删除最后一个
console.log(fruits.length); // 数组长度
5. 对象 (Object) - 属性集合
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

控制流程

if 语句 - 条件判断

let weather = "晴天";

if (weather === "晴天") {
  console.log("出去玩!");
} else if (weather === "雨天") {
  console.log("在家看书");
} else {
  console.log("看情况再说");
}

// 简写形式(三元运算符)
let message = weather === "晴天" ? "出去玩!" : "在家待着";

switch 语句 - 多选一

let day = "周一";

switch (day) {
  case "周一":
    console.log("新的一周开始!");
    break;
  case "周五":
    console.log("快到周末了!");
    break;
  case "周六":
  case "周日":
    console.log("休息日!");
    break;
  default:
    console.log("普通的一天");
}

循环 - 重复执行

for 循环 - 知道次数
// 打印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]);
}
while 循环 - 满足条件就继续
let count = 1;
while (count <= 3) {
  console.log(`计数:${count}`);
  count++;
}
for…of 循环 - 遍历数组(推荐)
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 - 承诺

// 创建 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/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);
  }
}

ES6+ 新特性

模板字符串

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)

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());

模块 (Modules)

// 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

高级概念

原型 (Prototype)

// 所有对象都有原型
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());

学习建议

1. 循序渐进

  • 先掌握基础语法
  • 多写小项目练习
  • 逐步学习高级概念

2. 实践为主

  • 每学一个概念就写代码练习
  • 做小项目巩固知识
  • 参与开源项目

3. 常用资源

  • MDN 文档(最权威)
  • JavaScript.info(很详细)
  • 浏览器开发者工具(调试必备)

4. 调试技巧

// 使用 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 的学习需要大量实践,不要只看不做! 每个概念都要亲自写代码验证,这样才能真正掌握。

祝你学习愉快!

你可能感兴趣的:(javascript,学习,开发语言)