news 2026/7/19 3:18:39

JavaScript从入门到精通:核心概念与实战技巧

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript从入门到精通:核心概念与实战技巧

1. JavaScript基础概览:从历史到现代应用

JavaScript诞生于1995年,由网景公司的Brendan Eich在短短10天内设计完成。这门语言最初被命名为LiveScript,后来为了蹭当时Java的热度才改名为JavaScript——尽管两者在语法特性上相似,但本质完全不同。作为前端开发的三大基石之一(HTML、CSS、JavaScript),现代JavaScript已经发展成一门能够处理复杂业务逻辑的全栈语言。

提示:虽然JavaScript和Java名称相似,但它们是两种完全不同的语言。Java需要编译后运行,而JavaScript是解释型语言,由浏览器直接执行。

在浏览器环境中,JavaScript通过DOM(文档对象模型)与页面交互。比如下面这段代码可以修改网页标题:

document.title = "新标题";

而在Node.js环境下,JavaScript可以像Python一样进行文件操作:

const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); });

1.1 数据类型与变量声明

JavaScript有7种原始数据类型:

  • Boolean:true/false
  • Null:表示空值
  • Undefined:未定义
  • Number:整数和浮点数
  • BigInt:大整数
  • String:字符串
  • Symbol:唯一标识符

以及1种复杂类型:

  • Object:对象

变量声明有三种方式:

var name = "老式声明"; // 函数作用域 let age = 25; // 块级作用域 const PI = 3.14; // 常量

注意:现代开发中应该避免使用var,优先使用const,需要重新赋值时才用let。const声明的数组和对象虽然不能重新赋值,但其内容是可以修改的。

1.2 类型转换的陷阱

JavaScript是弱类型语言,类型转换常常让新手困惑:

console.log(1 + "1"); // "11" (字符串拼接) console.log("2" * "3"); // 6 (自动转为数字) console.log([] == ![]); // true (抽象相等比较的奇怪结果)

建议总是使用严格相等比较:

console.log(0 === false); // false console.log(null === undefined); // false

2. 函数与作用域深度解析

2.1 函数的多种定义方式

函数声明:

function greet(name) { return `Hello, ${name}!`; }

函数表达式:

const greet = function(name) { return `Hello, ${name}!`; };

箭头函数(ES6):

const greet = (name) => `Hello, ${name}!`;

立即执行函数(IIFE):

(function() { console.log("立即执行"); })();

2.2 作用域与闭包

JavaScript采用词法作用域(静态作用域),函数在定义时就确定了作用域链:

function outer() { const x = 10; function inner() { console.log(x); // 可以访问外部变量 } return inner; } const closure = outer(); closure(); // 输出10

闭包的实际应用——创建私有变量:

function createCounter() { let count = 0; return { increment() { count++; }, getCount() { return count; } }; } const counter = createCounter(); counter.increment(); console.log(counter.getCount()); // 1 console.log(counter.count); // undefined (无法直接访问)

2.3 this关键字的迷思

this的值取决于函数的调用方式:

const obj = { name: "Alice", greet: function() { console.log(`Hello, ${this.name}`); } }; obj.greet(); // "Hello, Alice" (方法调用) const greetFunc = obj.greet; greetFunc(); // "Hello, undefined" (函数调用) // 使用bind固定this const boundGreet = obj.greet.bind(obj); boundGreet(); // "Hello, Alice"

箭头函数没有自己的this,它会捕获所在上下文的this值:

const obj = { name: "Bob", greet: function() { setTimeout(() => { console.log(`Hello, ${this.name}`); }, 100); } }; obj.greet(); // "Hello, Bob"

3. 面向对象编程与原型链

3.1 构造函数与class语法

传统构造函数方式:

function Person(name, age) { this.name = name; this.age = age; } Person.prototype.greet = function() { console.log(`Hi, I'm ${this.name}`); }; const alice = new Person("Alice", 25); alice.greet();

ES6 class语法(语法糖,底层仍是原型继承):

class Person { constructor(name, age) { this.name = name; this.age = age; } greet() { console.log(`Hi, I'm ${this.name}`); } } const bob = new Person("Bob", 30); bob.greet();

3.2 原型链机制

JavaScript使用原型链实现继承:

function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(`${this.name} is eating.`); }; function Dog(name, breed) { Animal.call(this, name); this.breed = breed; } Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; Dog.prototype.bark = function() { console.log("Woof!"); }; const myDog = new Dog("Rex", "Labrador"); myDog.eat(); // "Rex is eating." myDog.bark(); // "Woof!"

ES6继承语法更简洁:

class Animal { constructor(name) { this.name = name; } eat() { console.log(`${this.name} is eating.`); } } class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } bark() { console.log("Woof!"); } } const myDog = new Dog("Rex", "Labrador"); myDog.eat(); myDog.bark();

3.3 现代对象操作技巧

对象解构:

const person = { name: "Alice", age: 25, job: "Developer" }; const { name, age } = person; console.log(name, age); // "Alice" 25

展开运算符:

const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }

可选链操作符(?.):

const user = { profile: { name: "Alice" } }; console.log(user?.profile?.name); // "Alice" console.log(user?.address?.street); // undefined (不会报错)

4. 异步编程与现代JavaScript特性

4.1 从回调到Promise再到async/await

回调地狱示例:

function getUser(id, callback) { setTimeout(() => { callback({ id, name: `User${id}` }); }, 100); } getUser(1, (user) => { getUser(2, (user2) => { getUser(3, (user3) => { console.log([user, user2, user3]); }); }); });

Promise解决方案:

function getUser(id) { return new Promise((resolve) => { setTimeout(() => { resolve({ id, name: `User${id}` }); }, 100); }); } getUser(1) .then(user => getUser(2)) .then(user2 => getUser(3)) .then(user3 => { console.log([user, user2, user3]); });

async/await终极方案:

async function fetchUsers() { const user1 = await getUser(1); const user2 = await getUser(2); const user3 = await getUser(3); console.log([user1, user2, user3]); } fetchUsers();

4.2 常用数组操作方法

map/filter/reduce三剑客:

const numbers = [1, 2, 3, 4, 5]; // map: 转换数组 const doubled = numbers.map(n => n * 2); // filter: 过滤数组 const evens = numbers.filter(n => n % 2 === 0); // reduce: 累积计算 const sum = numbers.reduce((acc, n) => acc + n, 0); console.log({ doubled, evens, sum });

现代数组方法:

const users = [ { id: 1, name: "Alice", active: true }, { id: 2, name: "Bob", active: false }, { id: 3, name: "Charlie", active: true } ]; // find: 查找第一个符合条件的元素 const activeUser = users.find(user => user.active); // some: 是否有符合条件的元素 const hasInactive = users.some(user => !user.active); // every: 是否所有元素都符合条件 const allActive = users.every(user => user.active); console.log({ activeUser, hasInactive, allActive });

4.3 ES6+重要特性

模板字符串:

const name = "Alice"; const age = 25; console.log(`My name is ${name} and I'm ${age} years old.`);

默认参数:

function greet(name = "Guest") { console.log(`Hello, ${name}!`); } greet(); // "Hello, Guest!"

剩余参数与展开运算符:

function sum(...numbers) { return numbers.reduce((acc, n) => acc + n, 0); } console.log(sum(1, 2, 3)); // 6 const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

5. 错误处理与调试技巧

5.1 try-catch与错误类型

基本错误处理:

try { // 可能出错的代码 const data = JSON.parse('invalid json'); } catch (error) { console.error('解析出错:', error.message); } finally { console.log('无论成功失败都会执行'); }

自定义错误:

class ValidationError extends Error { constructor(message) { super(message); this.name = "ValidationError"; } } function validateInput(input) { if (!input) { throw new ValidationError("输入不能为空"); } } try { validateInput(""); } catch (error) { if (error instanceof ValidationError) { console.error("验证错误:", error.message); } else { console.error("未知错误:", error); } }

5.2 调试技巧与性能优化

console的进阶用法:

console.time("arrayTest"); const arr = Array(1000000).fill().map((_, i) => i); console.timeEnd("arrayTest"); // 输出执行时间 console.table([ { name: "Alice", age: 25 }, { name: "Bob", age: 30 } ]); // 条件输出 console.assert(1 === 2, "1不等于2"); // 只有条件为false时输出

性能优化建议:

  1. 避免在循环中创建函数
  2. 使用文档片段批量DOM操作
  3. 使用事件委托减少事件监听器
  4. 合理使用Web Worker处理耗时任务

内存泄漏常见原因:

  • 意外的全局变量
  • 未清除的定时器
  • DOM引用未释放
  • 闭包滥用

6. 模块化与现代开发工具

6.1 ES Modules基础

导出模块:

// math.js export function add(a, b) { return a + b; } export const PI = 3.14159;

导入模块:

// app.js import { add, PI } from './math.js'; console.log(add(2, 3)); // 5 console.log(PI); // 3.14159

默认导出:

// logger.js export default function(message) { console.log(`[LOG]: ${message}`); } // app.js import log from './logger.js'; log("Hello"); // "[LOG]: Hello"

6.2 常用开发工具配置

VS Code推荐插件:

  1. ESLint - JavaScript代码检查
  2. Prettier - 代码格式化
  3. JavaScript (ES6) code snippets - 代码片段
  4. Debugger for Chrome - 调试
  5. Jest - 测试支持

package.json常见脚本:

{ "scripts": { "start": "node src/index.js", "dev": "nodemon src/index.js", "test": "jest", "lint": "eslint .", "build": "webpack --mode production" } }

Babel配置示例(.babelrc):

{ "presets": [ ["@babel/preset-env", { "targets": { "browsers": ["last 2 versions", "not dead"] } }] ], "plugins": ["@babel/plugin-transform-runtime"] }

7. 实战案例与常见问题解决

7.1 表单验证实用案例

class FormValidator { constructor(formId) { this.form = document.getElementById(formId); this.errors = {}; this.form.addEventListener('submit', (e) => { e.preventDefault(); if (this.validate()) { this.form.submit(); } }); } validate() { this.errors = {}; const inputs = this.form.querySelectorAll('[data-validate]'); inputs.forEach(input => { const rules = input.dataset.validate.split('|'); rules.forEach(rule => { const [ruleName, param] = rule.split(':'); if (ruleName === 'required' && !input.value.trim()) { this.addError(input, '此字段为必填项'); } if (ruleName === 'min' && input.value.length < parseInt(param)) { this.addError(input, `至少需要${param}个字符`); } if (ruleName === 'email' && !/^\S+@\S+\.\S+$/.test(input.value)) { this.addError(input, '请输入有效的邮箱地址'); } }); }); return Object.keys(this.errors).length === 0; } addError(input, message) { if (!this.errors[input.name]) { this.errors[input.name] = []; } this.errors[input.name].push(message); // 显示错误提示 const errorElement = document.createElement('div'); errorElement.className = 'error-message'; errorElement.textContent = message; input.parentNode.appendChild(errorElement); } } // 使用示例 new FormValidator('myForm');

7.2 常见错误与解决方案

  1. Cannot read property 'xxx' of undefined/null原因:尝试访问未定义或null值的属性 解决方案:使用可选链操作符或条件判断

    // 不好的写法 const street = user.address.street; // 好的写法 const street = user?.address?.street; // 或 const street = user && user.address && user.address.street;
  2. Unexpected token '<'原因:通常是因为请求返回了HTML而不是预期的JSON 解决方案:检查API端点是否正确,确保返回的是JSON

  3. Maximum call stack size exceeded原因:无限递归调用 解决方案:检查递归函数的终止条件

  4. Cross-Origin Request Blocked原因:跨域请求被阻止 解决方案:配置CORS或使用代理

  5. TypeError: xxx is not a function原因:尝试调用非函数类型的值 解决方案:检查变量是否确实是一个函数

8. 性能优化与安全实践

8.1 前端性能优化技巧

  1. 减少重绘和回流

    • 使用transform和opacity实现动画
    • 批量DOM操作
    • 使用文档片段(document.createDocumentFragment())
  2. 代码分割与懒加载

    // 动态导入 const module = await import('./module.js'); // React中的懒加载 const LazyComponent = React.lazy(() => import('./LazyComponent'));
  3. 防抖与节流

    // 防抖:最后一次操作后等待一段时间执行 function debounce(fn, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, arguments), delay); }; } // 节流:固定时间间隔执行一次 function throttle(fn, interval) { let lastTime = 0; return function() { const now = Date.now(); if (now - lastTime >= interval) { fn.apply(this, arguments); lastTime = now; } }; }

8.2 JavaScript安全最佳实践

  1. 避免XSS攻击

    • 总是对用户输入进行转义
    • 使用textContent而不是innerHTML
    • 设置Content Security Policy (CSP)
  2. 防止CSRF攻击

    • 使用CSRF令牌
    • 设置SameSite cookie属性
  3. 安全存储敏感数据

    • 不要在前端存储密码等敏感信息
    • 使用HttpOnly和Secure标记的cookie
  4. 输入验证

    function sanitizeInput(input) { return input.replace(/</g, "&lt;").replace(/>/g, "&gt;"); }
  5. 使用安全的API

    • 避免使用eval()
    • 使用JSON.parse()而不是eval()解析JSON
    • 使用模板字符串而不是字符串拼接构建HTML

9. 测试与调试进阶

9.1 单元测试基础

使用Jest进行测试:

// math.js export function add(a, b) { return a + b; } // math.test.js import { add } from './math'; test('adds 1 + 2 to equal 3', () => { expect(add(1, 2)).toBe(3); }); describe('add function', () => { it('should add two numbers correctly', () => { expect(add(2, 3)).toBe(5); expect(add(-1, 1)).toBe(0); expect(add(0, 0)).toBe(0); }); });

9.2 调试技巧进阶

Chrome开发者工具技巧:

  1. 条件断点:右键点击行号,选择"Add conditional breakpoint"
  2. 日志点:在不修改代码的情况下添加console.log
  3. 黑盒脚本:忽略第三方库的调试
  4. 性能分析:使用Performance面板记录和分析运行时性能

Node.js调试:

node --inspect-brk app.js

然后在Chrome中访问chrome://inspect进行调试

9.3 错误监控与日志

Sentry集成示例:

import * as Sentry from '@sentry/browser'; Sentry.init({ dsn: 'YOUR_DSN_HERE', release: 'my-project@1.0.0', environment: 'production' }); try { riskyOperation(); } catch (error) { Sentry.captureException(error); }

自定义错误日志:

function logError(error, context = {}) { const errorData = { timestamp: new Date().toISOString(), message: error.message, stack: error.stack, ...context }; // 发送到服务器或保存到IndexedDB sendToServer('/log-error', errorData); }

10. 现代JavaScript生态系统

10.1 流行框架概览

  1. React

    import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}> Increment </button> </div> ); }
  2. Vue

    import { createApp, ref } from 'vue'; const app = createApp({ setup() { const count = ref(0); return { count, increment: () => count.value++ }; }, template: ` <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> </div> ` }); app.mount('#app');
  3. Angular

    import { Component } from '@angular/core'; @Component({ selector: 'app-counter', template: ` <div> <p>Count: {{ count }}</p> <button (click)="increment()">Increment</button> </div> ` }) export class CounterComponent { count = 0; increment() { this.count++; } }

10.2 构建工具比较

  1. Webpack

    • 高度可配置
    • 强大的代码分割能力
    • 丰富的插件生态系统
  2. Vite

    • 极快的启动速度
    • 原生ES模块支持
    • 开箱即用的配置
  3. Rollup

    • 适合库开发
    • 生成更小的包
    • 简单的配置

10.3 TypeScript基础

类型注解:

function greet(name: string): string { return `Hello, ${name}!`; } interface User { id: number; name: string; age?: number; // 可选属性 } const user: User = { id: 1, name: "Alice" };

泛型:

function identity<T>(arg: T): T { return arg; } const output = identity<string>("hello");

类与继承:

class Animal { constructor(public name: string) {} move(distance: number = 0) { console.log(`${this.name} moved ${distance}m.`); } } class Dog extends Animal { constructor(name: string, public breed: string) { super(name); } bark() { console.log("Woof!"); } } const myDog = new Dog("Rex", "Labrador"); myDog.bark(); myDog.move(10);

11. 浏览器API与Web标准

11.1 DOM操作最佳实践

高效DOM操作:

// 不好的做法:多次重排 for (let i = 0; i < 100; i++) { document.body.appendChild(document.createElement('div')); } // 好的做法:使用文档片段 const fragment = document.createDocumentFragment(); for (let i = 0; i < 100; i++) { fragment.appendChild(document.createElement('div')); } document.body.appendChild(fragment);

事件委托:

// 不好的做法:为每个元素添加监听器 document.querySelectorAll('.item').forEach(item => { item.addEventListener('click', handleClick); }); // 好的做法:事件委托 document.querySelector('.container').addEventListener('click', (e) => { if (e.target.matches('.item')) { handleClick(e); } });

11.2 现代浏览器API

Web Storage:

// localStorage localStorage.setItem('theme', 'dark'); const theme = localStorage.getItem('theme'); // sessionStorage sessionStorage.setItem('token', 'abc123');

Geolocation API:

navigator.geolocation.getCurrentPosition( (position) => { console.log(position.coords.latitude, position.coords.longitude); }, (error) => { console.error(error.message); } );

Web Workers:

// main.js const worker = new Worker('worker.js'); worker.postMessage({ data: 'Hello' }); worker.onmessage = (e) => { console.log('From worker:', e.data); }; // worker.js self.onmessage = (e) => { const result = e.data.data.toUpperCase(); self.postMessage(result); };

11.3 图形与动画API

Canvas基础:

const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); ctx.fillStyle = 'red'; ctx.fillRect(10, 10, 100, 100); ctx.beginPath(); ctx.arc(200, 75, 50, 0, Math.PI * 2); ctx.stroke();

WebGL入门:

const canvas = document.getElementById('glCanvas'); const gl = canvas.getContext('webgl'); if (!gl) { alert('WebGL not supported'); } gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT);

12. Node.js基础与全栈开发

12.1 Node.js核心模块

HTTP服务器:

const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); }); server.listen(3000, () => { console.log('Server running at http://localhost:3000/'); });

文件系统操作:

const fs = require('fs').promises; async function readFiles() { try { const data = await fs.readFile('file.txt', 'utf8'); console.log(data); await fs.writeFile('copy.txt', data); } catch (err) { console.error(err); } } readFiles();

12.2 Express框架基础

基本应用:

const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send('Hello World!'); }); app.post('/api/users', (req, res) => { // 处理POST请求 res.json({ success: true }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); });

中间件:

// 日志中间件 app.use((req, res, next) => { console.log(`${req.method} ${req.url}`); next(); }); // 静态文件服务 app.use(express.static('public')); // 解析JSON请求体 app.use(express.json());

12.3 数据库连接

MongoDB (Mongoose):

const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true }); const userSchema = new mongoose.Schema({ name: String, email: { type: String, required: true } }); const User = mongoose.model('User', userSchema); async function createUser() { const user = new User({ name: 'Alice', email: 'alice@example.com' }); await user.save(); console.log('User created:', user); } createUser();

SQL (Sequelize):

const { Sequelize, DataTypes } = require('sequelize'); const sequelize = new Sequelize('sqlite::memory:'); const User = sequelize.define('User', { name: DataTypes.STRING, email: { type: DataTypes.STRING, allowNull: false } }); async function test() { await sequelize.sync(); const user = await User.create({ name: 'Bob', email: 'bob@example.com' }); console.log(user.toJSON()); } test();

13. 设计模式与架构原则

13.1 常见JavaScript设计模式

单例模式:

class Logger { constructor() { if (Logger.instance) { return Logger.instance; } this.logs = []; Logger.instance = this; } log(message) { this.logs.push(message); console.log(message); } } const logger1 = new Logger(); const logger2 = new Logger(); console.log(logger1 === logger2); // true

观察者模式:

class EventEmitter { constructor() { this.events = {}; } on(event, listener) { if (!this.events[event]) { this.events[event] = []; } this.events[event].push(listener); } emit(event, ...args) { if (this.events[event]) { this.events[event].forEach(listener => listener(...args)); } } } const emitter = new EventEmitter(); emitter.on('data', (data) => { console.log('Received data:', data); }); emitter.emit('data', { id: 1 }); // "Received data: { id: 1 }"

工厂模式:

class Car { constructor(options) { this.model = options.model || 'Unknown'; this.year = options.year || new Date().getFullYear(); } } class Truck { constructor(options) { this.capacity = options.capacity || 1; this.model = options.model || 'Unknown'; } } class VehicleFactory { createVehicle(type, options) { switch (type) { case 'car': return new Car(options); case 'truck': return new Truck(options); default: throw new Error('Unknown vehicle type'); } } } const factory = new VehicleFactory(); const myCar = factory.createVehicle('car', { model: 'Sedan' }); const myTruck = factory.createVehicle('truck', { capacity: 5 });

13.2 SOLID原则应用

  1. 单一职责原则(SRP)

    // 不好的做法 class User { constructor(name, email) { this.name = name; this.email = email; } saveToDatabase() { // 保存到数据库 } sendEmail() { // 发送邮件 } } // 好的做法 class User { constructor(name, email) { this.name = name; this.email = email; } } class UserRepository { save(user) { // 保存到数据库 } } class EmailService { send(user, message) { // 发送邮件 } }
  2. 开闭原则(OCP)

    // 不好的做法 class Logger { log(message, type) { if (type === 'console') { console.log(message); } else if (type === 'file') { // 写入文件 } } } // 好的做法 class Logger { log(message) { throw new Error('Method not implemented'); } } class ConsoleLogger extends Logger { log(message) { console.log(message); } } class FileLogger extends Logger { log(message) { // 写入文件 } }
  3. 里氏替换原则(LSP)

    class Bird { fly() { console.log('Flying'); } } class Duck extends Bird { quack() { console.log('Quack'); } } class Penguin extends Bird { fly() { throw new Error('Penguins cannot fly'); } } // 违反LSP原则,因为Penguin不能替换Bird
  4. 接口隔离原则(ISP)

    // 不好的做法 class Worker { work() {} eat() {} } // 好的做法 class Workable { work() {} } class Eatable { eat() {} } class Worker implements Workable, Eatable { work() {} eat() {} } class Robot implements Workable { work() {} }
  5. 依赖倒置原则(DIP)

    // 不好的做法 class LightBulb { turnOn() {} turnOff() {} } class Switch { constructor(bulb) { this.bulb = bulb; } operate() { // 操作灯泡 } } // 好的做法 class Switchable { turnOn() {} turnOff() {} } class LightBulb implements Switchable { turnOn() {} turnOff() {} } class Switch { constructor(device) { this.device = device; } operate() { // 操作任何Switchable设备 } }

14. 算法与数据结构基础

14.1 常见算法实现

快速排序:

function quickSort(arr) { if (arr.length <= 1) return arr; const pivot = arr[0]; const left = []; const right = []; for (let i = 1; i < arr.length; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return [...quickSort(left), pivot, ...quickSort(right)]; } console.log(quickSort([3, 6, 8, 10, 1, 2, 1])); // [1, 1, 2, 3, 6, 8, 10]

二分查找:

function binarySearch(arr, target) { let left = 0; let right = arr.length - 1; while (left <= right) { const mid = Math.floor((left + right) / 2); if (arr[mid] === target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } const sortedArr = [1, 3, 5, 7, 9]; console.log(binarySearch(sortedArr, 5)); // 2 console.log(binarySearch(sortedArr, 2)); // -1

14.2 数据结构实现

链表:

class ListNode { constructor(value) { this.value = value; this.next = null; } } class LinkedList { constructor() { this.head = null; this.tail = null; this.length = 0; } append(value) { const newNode = new ListNode(value); if (!this.head) { this.head = newNode; this.tail = newNode; } else { this.tail.next = newNode; this.tail = newNode; } this.length++; } print() { let current = this.head; while (current) { console.log(current.value); current = current.next; } } } const list = new LinkedList(); list.append(1); list.append(2); list.append(3); list.print(); // 1, 2, 3

哈希表:

class HashTable { constructor(size = 53) { this.keyMap = new Array(size); } _hash(key) { let total = 0; const WEIRD_PRIME
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/19 3:17:24

高质量数据集建设为什么不能照搬传统数据治理逻辑

导语一家企业完成了持续多年的数据治理建设。核心业务系统已经接入数据平台&#xff0c;数据标准、元数据、主数据和质量规则陆续建立&#xff0c;主题库和指标体系也开始稳定运行。过去分散在不同部门和系统中的数据&#xff0c;已经可以被统一查询、关联和共享。按照传统数据…

作者头像 李华
网站建设 2026/7/19 3:17:13

fastdds笔记

1WriteParam3个参数&#xff1a;&#xff08;1&#xff09;source_timestamp:写时的时间戳&#xff0c;与时间有关的qos&#xff0c;比如deadline等&#xff0c;会使用这个时间戳&#xff0c;用户可以设置source_timestamp&#xff0c;write的时候通过FASTDDS_EXPORTED_API Ret…

作者头像 李华
网站建设 2026/7/19 3:15:56

嵌入式C语言

C语言数据类型在STM32中数据类型的关键字名字被换为&#xff1a;stdint关键字里对应的名称。使用新名称需要包含stdint.h头文件。C语言宏定义关键字&#xff1a;#define用途&#xff1a;用一个字符串代替一个数字&#xff0c;便于理解&#xff0c;防止出错&#xff1b;提取程序…

作者头像 李华
网站建设 2026/7/19 3:13:44

AI 时代的软件过程管理实践1:AI 到底让开发快了多少

在讲每一个具体领域之前&#xff0c;我想先说一说请 AI 做的一个估算。对于这个估算&#xff0c;我也是后知后觉的。在 AI 兴起的这段时间&#xff0c;我一直有个潜意识——“AI 去掉了开发难度&#xff0c;加速了开发进程&#xff0c;一个人配上 AI&#xff0c;顶得上过去一个…

作者头像 李华
网站建设 2026/7/19 3:12:29

Python基础语句详解:从赋值到控制流

1. Python语句基础概述Python作为一门简洁优雅的编程语言&#xff0c;其语句结构与其他主流语言有着显著区别。刚接触Python的开发者最需要适应的就是它独特的语法风格——用缩进来表示代码块&#xff0c;而不是像C/Java那样使用大括号。这种设计让Python代码看起来更加整洁&am…

作者头像 李华
网站建设 2026/7/19 3:12:16

缺失值处理不是填空题:从业务信号解码到工业级填充实战

1. 项目概述&#xff1a;为什么缺失值处理不是“填个数”那么简单你手头刚拿到一份客户提供的销售数据表&#xff0c;打开第一眼就发现“客单价”列里有237个空单元格&#xff0c;“复购周期”列里有112个NaN&#xff0c;“用户等级”列里混着“未知”“暂未评定”“—”三种非…

作者头像 李华