JavaScript

1- JavaScript 基础知识

1.1- 什么是 JavaScript?

JavaScript 是一种广泛用于网页开发的编程语言,它可以在浏览器和服务器端运行。JavaScript 使网页具有动态性和交互性,是前端开发的重要组成部分。

1.2- 基本语法

1.2.1- 变量声明

在 JavaScript 中,你可以使用 varletconst 来声明变量。

  • var:函数作用域或全局作用域,可以重新赋值,变量提升。
  • let:块级作用域,可以重新赋值,不会变量提升。
  • const:块级作用域,不可重新赋值,必须立即赋值,不会变量提升。

示例

// 使用 var 声明变量
var message = "Hello, World!";
console.log(message); // 输出: Hello, World!

// 使用 let 声明变量
let count = 0;
count = 1; // 正确,可以重新赋值
console.log(count); // 输出: 1

// 使用 const 声明变量
const PI = 3.14159;
// PI = 3.14; // 这将导致错误,因为 PI 是常量
console.log(PI); // 输出: 3.14159

1.2.2- 数据类型

JavaScript 有多种数据类型,包括基本数据类型和引用数据类型。

  • 基本数据类型

    • string:字符串,用单引号或双引号表示。
    • number:数字,可以是整数或浮点数。
    • boolean:布尔值,只有 truefalse 两种值。
    • null:空值,表示一个空对象指针。
    • undefined:未定义,表示变量已被声明但未赋值。
    • symbol(ES6 新增):唯一标识符,用于对象属性的键。
  • 引用数据类型

    • object:对象,可以包含多个属性。
    • array:数组,可以包含多个元素。
    • function:函数,可以执行一段代码。

示例

let name = "Alice"; // string
let age = 25; // number
let isStudent = true; // boolean
let person = { name: "Bob", age: 30 }; // object
let numbers = [1, 2, 3]; // array
let sum = function(a, b) { return a + b; }; // function

1.3- 控制结构

1.3.1- 条件语句

  • if 语句:根据条件执行代码块。
  • else if 语句:多个条件分支。
  • else 语句:默认执行的代码块。

示例

let age = 25;

if (age < 18) {
  console.log("You are a minor.");
} else if (age >= 18 && age < 65) {
  console.log("You are an adult.");
} else {
  console.log("You are a senior.");
}

1.3.2- 循环

  • for 循环:固定次数的循环。
  • while 循环:根据条件执行循环。
  • do...while 循环:至少执行一次循环。

示例

// for 循环
for (let i = 0; i < 5; i++) {
  console.log(i); // 输出: 0, 1, 2, 3, 4
}

// while 循环
let count = 0;
while (count < 5) {
  console.log(count); // 输出: 0, 1, 2, 3, 4
  count++;
}

// do...while 循环
let count = 0;
do {
  console.log(count); // 输出: 0, 1, 2, 3, 4
  count++;
} while (count < 5);

1.4- 函数

1.4.1- 函数声明

  • 函数声明:定义一个函数并命名。
  • 函数表达式:将函数赋值给一个变量。

示例

// 函数声明
function greet(name) {
  return "Hello, " + name;
}

console.log(greet("Alice")); // 输出: Hello, Alice

// 函数表达式
const sayHi = function(name) {
  return "Hi, " + name;
};

console.log(sayHi("Bob")); // 输出: Hi, Bob

1.4.2- 箭头函数(ES6 新增)

  • 箭头函数:简化函数的语法。

示例

const add = (a, b) => a + b;
console.log(add(5, 3)); // 输出: 8

1.5- 数组

1.5.1- 基本操作

  • 创建数组:使用数组字面量或 Array 构造函数。
  • 访问元素:使用索引访问数组元素。
  • 数组方法:如 pushpopshiftunshiftslicesplice 等。

示例

let numbers = [1, 2, 3, 4, 5];

// 访问元素
console.log(numbers[0]); // 输出: 1

// 添加元素
numbers.push(6); // 在数组末尾添加元素
console.log(numbers); // 输出: [1, 2, 3, 4, 5, 6]

// 删除元素
numbers.pop(); // 删除数组末尾的元素
console.log(numbers); // 输出: [1, 2, 3, 4, 5]

// 插入元素
numbers.unshift(0); // 在数组开头插入元素
console.log(numbers); // 输出: [0, 1, 2, 3, 4, 5]

// 删除元素
numbers.shift(); // 删除数组开头的元素
console.log(numbers); // 输出: [1, 2, 3, 4, 5]

// 切割数组
let sliced = numbers.slice(1, 3); // 切割数组,返回索引 1 到 2 的元素
console.log(sliced); // 输出: [2, 3]

// 修改数组
numbers.splice(1, 2, "a", "b"); // 从索引 1 开始删除 2 个元素,然后插入 "a" 和 "b"
console.log(numbers); // 输出: [1, "a", "b", 4, 5]

1.6- 对象

1.6.1- 基本操作

  • 创建对象:使用对象字面量或 Object 构造函数。
  • 访问属性:使用点操作符或方括号。
  • 添加/修改属性:直接赋值。
  • 删除属性:使用 delete 关键字。

示例

// 创建对象
let person = {
  name: "Alice",
  age: 25,
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

// 访问属性
console.log(person.name); // 输出: Alice
console.log(person["age"]); // 输出: 25

// 添加/修改属性
person.age = 26;
person.city = "New York";

// 删除属性
delete person.city;

// 调用方法
person.greet(); // 输出: Hello, my name is Alice

1.7- DOM 操作

1.7.1- 获取元素

  • document.getElementById:通过 ID 获取元素。
  • document.querySelector:通过 CSS 选择器获取第一个匹配的元素。
  • document.querySelectorAll:通过 CSS 选择器获取所有匹配的元素。

示例

<!DOCTYPE html>
<html>
<head>
  <title>DOM 操作示例</title>
</head>
<body>
  <h1 id="heading">Hello, World!</h1>
  <p class="message">This is a message.</p>
  <p class="message">This is another message.</p>

  <script>
    // 获取元素
    let heading = document.getElementById("heading");
    let firstMessage = document.querySelector(".message");
    let messages = document.querySelectorAll(".message");

    // 修改元素内容
    heading.textContent = "Hello, JavaScript!";
    firstMessage.textContent = "This is the first message.";
    messages[1].textContent = "This is the second message.";

    // 添加元素
    let newParagraph = document.createElement("p");
    newParagraph.textContent = "This is a new paragraph.";
    document.body.appendChild(newParagraph);

    // 删除元素
    document.body.removeChild(firstMessage);
  </script>
</body>
</html>

1.8- 事件处理

1.8.1- 添加事件监听器

  • addEventListener:为元素添加事件监听器。

示例

<!DOCTYPE html>
<html>
<head>
  <title>事件处理示例</title>
</head>
<body>
  <button id="myButton">Click me!</button>

  <script>
    // 获取按钮元素
    let button = document.getElementById("myButton");

    // 添加点击事件监听器
    button.addEventListener("click", function() {
      alert("Button clicked!");
    });
  </script>
</body>
</html>

1.9- 异步编程

1.9.1- 回调函数

  • 回调函数:将一个函数作为参数传递给另一个函数,并在适当的时候调用。

示例

function fetchData(callback) {
  setTimeout(() => {
    let data = "Some data";
    callback(data);
  }, 2000);
}

fetchData(function(data) {
  console.log(data); // 输出: Some data
});

1.9.2- Promise

  • Promise:表示一个异步操作的最终完成(或失败)及其结果值。

示例

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let data = "Some data";
      resolve(data);
    }, 2000);
  });
}

fetchData().then(data => {
  console.log(data); // 输出: Some data
}).catch(error => {
  console.error(error);
});

1.9.3- async/await

  • async/await:使异步代码看起来更像同步代码,更容易理解和维护。

示例

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let data = "Some data";
      resolve(data);
    }, 2000);
  });
}

async function getData() {
  try {
    let data = await fetchData();
    console.log(data); // 输出: Some data
  } catch (error) {
    console.error(error);
  }
}

getData();

1.10- 最佳实践

  1. 使用严格模式:在代码顶部添加 'use strict';,以启用严格模式,帮助你避免一些常见的错误。
  2. 模块化:将代码拆分成多个模块,提高可维护性和复用性。
  3. 代码注释:为代码添加注释,帮助其他人(包括未来的你)更好地理解代码。
  4. 代码格式化:使用代码格式化工具(如 Prettier)保持代码风格一致。
  5. 性能优化:关注代码的性能,避免不必要的计算和 DOM 操作。

2- 总结

JavaScript 是一种强大而灵活的编程语言,广泛应用于网页开发。掌握基本语法、控制结构、函数、数组、对象、DOM 操作、事件处理和异步编程是成为 JavaScript 开发者的必备技能。希望这个文档能帮助你更好地理解和使用 JavaScript。如果你有更多问题或需要进一步的信息,请随时告诉我!

3- 常见问题解答

3.1- Q1: 什么是变量提升?

A1: 变量提升是指在 JavaScript 中,变量声明会被提升到其作用域的顶部,但初始化不会。这意味着你可以在声明变量之前使用它,但它的值会是 undefined

示例

console.log(message); // 输出: undefined
var message = "Hello, World!";

3.2- Q2: letconst 有什么区别?

A2: letconst 都是块级作用域,但 let 可以重新赋值,而 const 不能重新赋值。const 声明的变量必须在声明时立即赋值。

示例

let count = 0;
count = 1; // 正确,可以重新赋值

const PI = 3.14159;
// PI = 3.14; // 这将导致错误,因为 PI 是常量

3.3- Q3: 什么是闭包?

A3: 闭包是指一个函数能够记住并访问其词法作用域,即使这个函数在其词法作用域之外执行。闭包在 JavaScript 中非常有用,可以用于创建私有变量和模块化代码。

示例

function createCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 输出: 1
console.log(counter()); // 输出: 2
console.log(counter()); // 输出: 3

3.4- Q4: 什么是异步编程?

A4: 异步编程是指在不阻塞主线程的情况下执行任务。JavaScript 中的异步编程主要通过回调函数、Promise 和 async/await 来实现。异步编程可以提高应用程序的性能和响应性。

示例

// 回调函数
function fetchData(callback) {
  setTimeout(() => {
    let data = "Some data";
    callback(data);
  }, 2000);
}

fetchData(function(data) {
  console.log(data); // 输出: Some data
});

// Promise
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let data = "Some data";
      resolve(data);
    }, 2000);
  });
}

fetchData().then(data => {
  console.log(data); // 输出: Some data
}).catch(error => {
  console.error(error);
});

// async/await
async function getData() {
  try {
    let data = await fetchData();
    console.log(data); // 输出: Some data
  } catch (error) {
    console.error(error);
  }
}

getData();