现代JavaScript全方位入门教程

JavaScript是Web的编程语言,用于创建动态和交互式的用户体验。本教程将引导你从零开始,掌握这门强大的语言。

1. 基础与变量

JavaScript代码通常放在 <script> 标签中。变量是用于存储数据值的容器。在现代JS中,我们使用 let (可变变量) 和 const (常量) 来声明变量。

console.log() 是一个非常有用的工具,可以在浏览器的开发者控制台打印信息,便于调试。

操作:点击按钮,然后在你的浏览器开发者工具(F12)的控制台中查看输出。

// 当ID为 'var-btn' 的按钮被点击时...
document.getElementById('var-btn').addEventListener('click', () => {
  // 声明一个可变变量
  let message = "你好, JavaScript!";
  console.log(message); // 在控制台打印消息

  // 改变变量的值
  message = "变量的值已经改变。";
  console.log(message);

  // 声明一个常量
  const PI = 3.14;
  console.log("这是一个常量: ", PI);
  // PI = 3.14159; // 这行代码会报错,因为常量不能被重新赋值
});

2. 数据类型

JavaScript有多种数据类型,包括基本类型(字符串、数字、布尔、null、undefined)和复杂类型(对象)。

const stringVar = "这是一个字符串";
const numberVar = 100;
const booleanVar = true;
const nullVar = null;
const undefinedVar = undefined;
const objectVar = { name: "张三", age: 30 };

// typeof 操作符可以返回变量的数据类型
document.getElementById('types-btn').onclick = () => {
  const output = `
    '${stringVar}' 是 ${typeof stringVar}<br>
    ${numberVar} 是 ${typeof numberVar}<br>
    ${booleanVar} 是 ${typeof booleanVar}<br>
    ${nullVar} 是 ${typeof nullVar} (注意: 这是一个历史遗留bug)<br>
    ${undefinedVar} 是 ${typeof undefinedVar}<br>
    对象 是 ${typeof objectVar}
  `;
  document.getElementById('types-output').innerHTML = output;
};

3. 运算符

运算符用于对变量和值执行操作。

重点: === (严格相等) 会比较值和类型,而 == (宽松相等) 会尝试类型转换。推荐始终使用 ===

document.getElementById('op-btn').onclick = () => {
  const num1 = Number(document.getElementById('op-num1').value);
  const num2 = Number(document.getElementById('op-num2').value);

  const sum = num1 + num2; // 加法
  const difference = num1 - num2; // 减法
  const product = num1 * num2; // 乘法
  const quotient = num1 / num2; // 除法

  document.getElementById('op-output').innerHTML = `和: ${sum}, 差: ${difference}, 积: ${product}, 商: ${quotient}`;
};

4. 条件与控制流

使用 if...else 语句,可以根据不同的条件执行不同的代码块。

document.getElementById('age-btn').onclick = () => {
  const age = document.getElementById('age-input').value;
  let result;

  if (age < 18) {
    result = "你还是个少年。";
  } else if (age >= 18 && age < 60) {
    result = "你是正值壮年的成年人。";
  } else {
    result = "你是一位智慧的长者。";
  }
  document.getElementById('age-output').textContent = result;
};

5. 循环

循环可以重复执行一段代码。for 循环是最常见的循环类型。

document.getElementById('loop-btn').onclick = () => {
  const list = document.getElementById('loop-output');
  list.innerHTML = ''; // 清空列表

  // for循环:从0到4,每次加1
  for (let i = 0; i < 5; i++) {
    // 创建一个新的列表项元素
    const listItem = document.createElement('li');
    listItem.textContent = `这是列表项 #${i + 1}`;
    // 将列表项添加到ul中
    list.appendChild(listItem);
  }
};

6. 函数

函数是一段可重复使用的代码块。你可以通过函数名来调用它,并可以向其传递参数。

// 定义一个名为 'greet' 的函数,它接受一个参数 'name'
function greet(name) {
  // 如果name为空,则提供一个默认值
  const finalName = name || "陌生人";
  return `你好, ${finalName}!`; // 返回一个拼接好的字符串
}

document.getElementById('func-btn').onclick = () => {
  const userName = document.getElementById('name-input').value;
  // 调用函数,并将结果显示在页面上
  document.getElementById('func-output').textContent = greet(userName);
};

7. 数组与对象

数组是值的有序列表。对象是键值对的无序集合。

// 这是一个对象数组,是实际开发中非常常见的数据结构
const users = [
  { id: 1, name: "爱丽丝", profession: "工程师" },
  { id: 2, name: "鲍勃", profession: "设计师" },
  { id: 3, name: "查理", profession: "项目经理" }
];

document.getElementById('data-btn').onclick = () => {
  const outputDiv = document.getElementById('data-output');
  outputDiv.innerHTML = '';

  // 使用 forEach 方法遍历数组
  users.forEach(user => {
    outputDiv.innerHTML += `用户: ${user.name}, 职业: ${user.profession}<br>`;
  });
};

8. DOM 操作

DOM (文档对象模型) 是HTML页面的编程接口。JavaScript可以通过DOM来动态地改变页面内容、结构和样式。

这是一段初始文本。

// 1. 获取元素
const textElement = document.getElementById('dom-text');

// 2. 改变文本内容
document.getElementById('dom-change-text-btn').onclick = () => {
  textElement.textContent = "文本已经被JavaScript改变了!";
};

// 3. 通过切换CSS类来改变样式
document.getElementById('dom-toggle-style-btn').onclick = () => {
  textElement.classList.toggle('style-changed');
};

9. 事件处理

JavaScript可以监听并响应用户的各种操作,如点击、鼠标移动、键盘输入等。这称为事件处理。

把鼠标移到我上面
const clickBtn = document.getElementById('event-click-btn');
const hoverArea = document.getElementById('event-hover-area');
const keyInput = document.getElementById('event-key-input');
const eventOutput = document.getElementById('event-output');

// 监听'click' (点击) 事件
clickBtn.addEventListener('click', () => {
  eventOutput.textContent = "按钮被点击了!";
});

// 监听'mouseover' (鼠标移入) 事件
hoverArea.addEventListener('mouseover', () => {
  eventOutput.textContent = "鼠标进入了指定区域!";
});

// 监听'keyup' (键盘按键抬起) 事件
keyInput.addEventListener('keyup', (event) => {
  // event.target.value 获取输入框的当前值
  eventOutput.textContent = `你输入了: ${event.target.value}`;
});

10. 异步编程

JavaScript是单线程的,但通过异步编程,它可以执行耗时操作(如网络请求)而不会阻塞主线程。async/await 是处理异步操作的现代语法,它基于Promise

下面的例子会从一个公共API获取一条随机的“**猫猫**”事实。

正在等待数据...
// 'async' 关键字表示这是一个异步函数
async function fetchCatFact() {
  const outputDiv = document.getElementById('async-output');
  outputDiv.textContent = '正在获取数据...';

  try {
    // 'await' 关键字会暂停函数执行,直到Promise完成(即网络请求返回)
    const response = await fetch('https://catfact.ninja/fact');

    // 将返回的数据解析为JSON格式
    const data = await response.json();

    // 更新页面内容 (根据新的API结构,事实在 data.fact 中)
    outputDiv.textContent = data.fact;
  } catch (error) {
    // 如果网络请求失败,捕获错误
    outputDiv.textContent = '获取数据失败,请重试。';
    console.error('Fetch error:', error);
  }
}

document.getElementById('async-btn').addEventListener('click', fetchCatFact);