JavaScript

01_基本语法和数据类型

变量、数据类型、运算符、条件语句、循环语句等基本语法和数据类型。

// 变量声明和赋值
let name = "John";
const age = 30;
var isAdmin = true;

// 数据类型
let num = 10; // Number
let str = "Hello"; // String
let bool = true; // Boolean
let arr = [1, 2, 3]; // Array
let obj = { name: "John", age: 30 }; // Object
let n = null; // Null
let u = undefined; // Undefined

// 运算符
let sum = 10 + 5; // 加法
let difference = 10 - 5; // 减法
let product = 10 * 5; // 乘法
let quotient = 10 / 5; // 除法
let remainder = 10 % 3; // 取余
let increment = 10++; // 自增
let decrement = 10--; // 自减

// 条件语句
if (isAdmin) {
    console.log("User is an admin");
} else if (age >= 18) {
    console.log("User is an adult");
} else {
    console.log("User is a minor");
}

// 循环语句
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

let i = 0;
while (i < arr.length) {
    console.log(arr[i]);
    i++;
}

// 函数声明
function greet(name) {
    console.log("Hello, " + name + "!");
}

// 调用函数
greet("John");

02_函数和作用域

函数的定义、调用、参数传递、作用域链、闭包等相关概念和用法。

// 函数的定义和调用
function greet(name) {
  console.log("Hello, " + name + "!");
}

// 调用函数
greet("John");

// 函数参数传递
function add(a, b) {
  return a + b;
}

let result = add(5, 3);
console.log("Sum:", result);

// 函数作用域
let x = 10;

function printX() {
  let y = 20;
  console.log("x inside function:", x); // x 是全局变量,在函数内部可以访问
  console.log("y inside function:", y); // y 是函数内部定义的局部变量
}

printX();
console.log("x outside function:", x); // x 是全局变量,在函数外部可以访问
// console.log("y outside function:", y); // y 是函数内部的局部变量,在函数外部无法访问,会报错

// 闭包
function outerFunction() {
  let outerVar = "I'm outer!";

  function innerFunction() {
    console.log(outerVar); // 内部函数可以访问外部函数的变量
  }

  return innerFunction;
}

let innerFunc = outerFunction();
innerFunc(); // 调用内部函数,打印 "I'm outer!"

03_对象和原型链

对象的创建、属性和方法的添加、访问、原型和原型链的概念,以及构造函数和原型继承等。

// 对象的创建和属性访问
let person = {
  name: "John",
  age: 30,
  greet: function () {
    console.log(
      "Hello, my name is " + this.name + " and I'm " + this.age + " years old.",
    );
  },
};

console.log("Name:", person.name); // 访问对象属性
console.log("Age:", person["age"]); // 使用方括号访问对象属性
person.greet(); // 调用对象方法

// 构造函数和原型
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function () {
  console.log(
    "Hello, my name is " + this.name + " and I'm " + this.age + " years old.",
  );
};

let john = new Person("John", 30);
console.log("Name:", john.name);
console.log("Age:", john.age);
john.greet();

// 原型链继承
function Student(name, age, grade) {
  Person.call(this, name, age); // 调用父类构造函数
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype); // 设置原型链
Student.prototype.constructor = Student; // 修复构造函数指向

let jane = new Student("Jane", 25, "A");
console.log("Name:", jane.name);
console.log("Age:", jane.age);
console.log("Grade:", jane.grade);
jane.greet(); // 子类继承父类方法

04_异步编程

事件循环、回调函数、Promise、async/await等用于处理异步操作的方式。

// 回调函数示例
function fetchData(callback) {
  setTimeout(() => {
    callback("Data fetched successfully");
  }, 1000);
}

fetchData((data) => {
  console.log(data);
});

// Promise 示例
function fetchDataPromise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data fetched successfully");
    }, 1000);
  });
}

fetchDataPromise()
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error("Error:", error);
  });

// async/await 示例
async function fetchDataAsync() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data fetched successfully");
    }, 1000);
  });
}

async function fetchDataWrapper() {
  try {
    const data = await fetchDataAsync();
    console.log(data);
  } catch (error) {
    console.error("Error:", error);
  }
}

fetchDataWrapper();

05_DOM操作

通过JavaScript操作文档对象模型(DOM)实现页面交互、动态内容更新等。

  1. 获取元素
    • getElementById(id):根据 id 获取元素。
    • getElementsByClassName(className):根据类名获取元素集合。
    • getElementsByTagName(tagName):根据标签名获取元素集合。
    • querySelector(selector):根据 CSS 选择器获取第一个匹配的元素。
    • querySelectorAll(selector):根据 CSS 选择器获取所有匹配的元素。
  2. 添加、移除和替换元素
    • appendChild(node):在指定节点的子节点列表末尾添加新的子节点。
    • removeChild(node):从父节点中移除子节点。
    • replaceChild(newNode, oldNode):用新节点替换旧节点。
  3. 样式操作
    • element.style.property = value:直接修改元素的内联样式。
    • classList.add(className):向元素添加类。
    • classList.remove(className):从元素中移除类。
    • classList.toggle(className):如果存在(不存在)就删除(添加)一个类。
  4. 内容操作
    • innerHTML:获取或设置元素的 HTML 内容。
    • textContent:获取或设置元素的文本内容。
  5. 属性操作
    • getAttribute(name):获取元素的指定属性值。
    • setAttribute(name, value):设置元素的指定属性值。
  6. 遍历节点
    • parentNode:获取父节点。
    • childNodes:获取所有子节点。
    • nextSiblingpreviousSibling:获取下一个和上一个兄弟节点。
  7. 事件监听
    • element.addEventListener(event, function):向指定元素添加事件监听器。
    • element.removeEventListener(event, function):从指定元素移除事件监听器。

06_浏览器事件

处理用户交互事件,例如点击、输入、鼠标移动等。

  1. click:鼠标点击的时候出发
  2. mouseover:鼠标移动到元素上方时触发。
  3. mouseout:鼠标移出元素时触发。
  4. mousedown:鼠标按下时触发。
  5. mouseup:鼠标松开时触发。
  6. mousemove:鼠标移动时触发。
  7. keydown:键盘按下时触发。
  8. keyup:键盘松开时触发。
  9. focus:元素获得焦点时触发。
  10. blur:元素失去焦点时触发。
  11. input:输入框的内容发生变化时触发。
  12. change:表单元素的值发生改变时触发。

tip:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>DOM 事件示例</title>
  </head>
  <body>
    <button id="myButton">点击我</button>
    <input type="text" id="myInput" placeholder="输入框" />

    <!-- 引入 JavaScript 文件 -->
    <script src="script.js"></script>
  </body>
</html>
// 获取按钮元素
const button = document.getElementById("myButton");

// 添加 click 事件监听器
button.addEventListener("click", function (event) {
  alert("按钮被点击了!");
});

// 获取输入框元素
const input = document.getElementById("myInput");

// 添加 input 事件监听器
input.addEventListener("input", function (event) {
  console.log("输入框的内容发生变化:", input.value);
});

// 添加 focus 和 blur 事件监听器
input.addEventListener("focus", function (event) {
  console.log("输入框获得焦点");
});

input.addEventListener("blur", function (event) {
  console.log("输入框失去焦点");
});

07_AJAX和HTTP请求

通过XMLHttpRequest或Fetch API进行网络请求,获取数据并更新页面。

AJAX(Asynchronous JavaScript and XML):

  • 是一种使用 JavaScript 进行异步通信的技术,可以在不重新加载整个页面的情况下,通过在后台与服务器进行数据交换来更新部分网页内容。
  • AJAX 技术通常使用 XMLHttpRequest 对象来实现。

tip:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AJAX Example</title>
  </head>
  <body>
    <div id="result"></div>

    <script src="ajax.js"></script>
  </body>
</html>
// 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();

// 配置请求
xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1", true);

// 监听请求状态变化
xhr.onreadystatechange = function () {
  if (xhr.readyState === XMLHttpRequest.DONE) {
    if (xhr.status === 200) {
      // 处理成功响应
      var responseData = JSON.parse(xhr.responseText);
      document.getElementById("result").innerText = responseData.title;
    } else {
      // 处理错误响应
      console.error("Request failed:", xhr.status);
    }
  }
};

// 发送请求
xhr.send();

Fetch API

  • 是一种新的 Web API,提供了一种更简洁、更强大的方式来进行网络请求。
  • 使用 Promise 对象处理异步操作,提供了更好的语法和功能。
  • Fetch API 不限于 XML 数据,可以与 JSON、HTML、Text 等各种格式的数据一起使用。

tip:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fetch API 示例</title>
  </head>
  <body>
    <h1>Fetch API 示例</h1>
    <button id="fetchButton">发起请求</button>
    <div id="result"></div>

    <script src="script.js"></script>
  </body>
</html>
document.getElementById("fetchButton").addEventListener("click", function () {
  const url = "https://jsonplaceholder.typicode.com/posts/1";
  fetch(url)
    .then((response) => {
      if (!response.ok) {
        throw new Error("Network response was not ok");
      }
      return response.json();
    })
    .then((data) => {
      document.getElementById("result").innerText = JSON.stringify(
        data,
        null,
        2,
      );
    })
    .catch((error) => {
      console.error("There was a problem with the fetch operation:", error);
    });
});

08_ES6及以上新特性

箭头函数、模板字符串、解构赋值、类、模块化等新的JavaScript语言特性。

// 模块化
// user.js
export class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
  }
}

// index.js
import { User } from "./user.js";

// 箭头函数
const printUserInfo = (user) => {
  console.log(user.greet());
};

// 解构赋值
const userData = {
  name: "Alice",
  age: 30,
};

const { name, age } = userData;

// 创建用户实例
const user = new User(name, age);

// 打印用户信息
printUserInfo(user);

0_9闭包和高阶函数(todo )

利用闭包实现函数封装和信息隐藏,以及高阶函数的概念和应用。

// 闭包示例
function outerFunction() {
  let outerVariable = "I am from outer function";

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

const innerFunc = outerFunction(); // 内部函数 innerFunction 成为闭包
innerFunc(); // 打印 "I am from outer function"

// 高阶函数示例
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

function calculate(operation, a, b) {
  return operation(a, b);
}

console.log(calculate(add, 5, 3)); // 调用 add 函数,打印 8
console.log(calculate(subtract, 5, 3)); // 调用 subtract 函数,打印 2

错误处理和调试:处理异常、调试技巧、错误日志记录等与错误处理相关的知识。

  1. 异常处理(Error Handling):
try {
  // 可能会抛出异常的代码块
  const result = someFunction();
  console.log(result);
} catch (error) {
  // 捕获异常并进行处理
  console.error("An error occurred:", error.message);
} finally {
  // 可选的 finally 块,无论是否发生异常都会执行
  console.log("Finally block executed");
}

在上面的代码中,try 块包含了可能会抛出异常的代码,catch 块用于捕获异常并进行处理,finally 块是可选的,无论是否发生异常都会执行。

  1. 调试技巧:
// 在代码中插入断点
debugger;

// 使用 console.log() 输出调试信息
console.log("Debug message:", variable);

// 使用 console.error() 输出错误信息
console.error("Error occurred:", error);

// 使用 console.trace() 输出函数调用堆栈
console.trace();

上面展示了一些常用的调试技巧,包括插入断点、使用 console.log() 输出调试信息、使用 console.error() 输出错误信息以及使用 console.trace() 输出函数调用堆栈。

  1. 错误日志记录(Error Logging):
// 使用 try-catch 捕获异常,并将异常信息记录到日志中
try {
  // 可能会抛出异常的代码块
  const result = someFunction();
  console.log(result);
} catch (error) {
  // 记录异常信息到日志中
  logError(error);
}

// 日志记录函数
function logError(error) {
  // 将错误信息发送到服务器或者保存到本地文件中
  console.error("Error logged:", error);
}

在实际项目中,我们通常会将错误信息记录到日志中,以便后续分析和排查问题。可以将错误信息发送到服务器或者保存到本地文件中。

  1. JavaScript框架和库:学习常用的JavaScript框架和库,例如React、Vue、Angular等,以及相关的概念和用法。
  2. 测试和优化:编写JavaScript单元测试、性能优化、代码规范等与代码质量相关的知识。