JS笔记(对象、函数、数组)

'# JS笔记(对象、函数、数组)

一、背景与问题

在JavaScript开发中,对象、函数和数组构成了程序的三大核心数据结构。理解它们的底层机制和使用规范,是构建高质量代码的基础。

1.1 核心挑战

  • 对象的原型链继承机制
  • 函数的闭包与this绑定
  • 数组的内存管理与性能优化
  • 跨平台兼容性问题(如ES5与ES6的差异)

1.2 常见误区

  • 对原型链继承的误解(如认为构造函数直接创建实例)
  • 函数参数传递的引用类型问题
  • 数组方法的副作用(如mutating原数组)

二、基本原理

2.1 对象的底层机制

2.1.1 原型链结构

JavaScript对象通过原型链实现继承,每个对象都有一个__proto__属性指向原型对象。

function Person(name) {
  this.name = name;
}

Person.prototype.sayHi = function() {
  console.log(`Hi, I'm ${this.name}`);
};

const p = new Person("Alice");
p.sayHi(); // Hi, I'm Alice

2.1.2 原型链查找机制

当访问对象属性时,会沿着原型链向上查找,直到找到或到达Object.prototype

2.1.3 构造函数与实例关系

构造函数的prototype属性指向原型对象,而实例的__proto__指向构造函数的prototype

2.1.4 禁用原型链的解决方案

Object.defineProperty(Person, 'prototype', {
  writable: false
});

2.2 函数的特殊性

2.2.1 函数对象特性

函数是对象,具有prototype属性,同时具有this绑定。

function add(a, b) {
  return a + b;
}

console.log(add.prototype); // {}

2.2.2 闭包的内存管理

闭包会捕获外层函数的变量,可能导致内存泄漏。

2.2.3 箭头函数的this绑定

箭头函数没有自己的this,继承自外层作用域。

const obj = {
  name: "Alice",
  sayHi: function() {
    setTimeout(() => {
      console.log(this.name); // Alice
    }, 100);
  }
};

2.3 数组的内存模型

2.3.1 数组的底层实现

JavaScript数组是动态数组,基于哈希表实现,支持稀疏性。

const arr = [1, 2, 3];
arr[10] = 100; // 稀疏数组

2.3.2 数组方法的性能差异

方法时间复杂度特点
pushO(1)可能引发扩容
popO(1)可能引发扩容
shiftO(n)头部删除
unshiftO(n)头部插入
mapO(n)不修改原数组
filterO(n)不修改原数组

2.3.3 内存管理策略

  • 使用Array.from代替new Array()创建数组
  • 避免使用delete操作符(会留下稀疏性)

三、环境准备

# 安装Node.js环境
npm init -y
npm install --save-dev eslint typescript

四、核心实现

4.1 对象的创建与继承

4.1.1 构造函数模式

function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(`${this.name} makes a noise`);
};

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // Buddy makes a noise

4.1.2 ES6类继承

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a noise`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
}

const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // Buddy makes a noise

4.2 函数的高级用法

4.2.1 闭包应用

function createCounter() {
  let count = 0;
  return {
    increment: () => count++,
    getCount: () => count
  };
}

const counter = createCounter();
console.log(counter.getCount()); // 0
counter.increment();
console.log(counter.getCount()); // 1

4.2.2 高阶函数应用

function applyOperation(arr, operation) {
  return arr.map(operation);
}

const numbers = [1, 2, 3];
const squared = applyOperation(numbers, x => x * x);
console.log(squared); // [1, 4, 9]

4.3 数组的高级操作

4.3.1 精确拷贝

const original = [1, 2, 3];
const copy = [...original]; // 浅拷贝
const deepCopy = JSON.parse(JSON.stringify(original)); // 深拷贝

4.3.2 性能优化技巧

// 使用Array.from代替new Array
const arr1 = Array.from({length: 10000}, (_, i) => i);
const arr2 = new Array(10000).fill(0).map((_, i) => i);

五、完整案例

5.1 用户数据处理系统

5.1.1 项目结构

user-system/
├── src/
│   ├── data/
│   │   └── users.json
│   ├── utils/
│   │   └── arrayUtils.js
│   ├── models/
│   │   └── User.js
│   └── main.js
├── package.json
└── README.md

5.1.2 用户数据模型

// src/models/User.js
class User {
  constructor(id, name, email, role) {
    this.id = id;
    this.name = name;
    this.email = email;
    this.role = role;
  }
  
  get isAdministrator() {
    return this.role === 'admin';
  }
}

5.1.3 数组处理工具

// src/utils/arrayUtils.js
export function filterActiveUsers(users) {
  return users.filter(user => user.isActive);
}

export function groupBy(users, key) {
  return users.reduce((acc, user) => {
    const value = user[key];
    if (!acc[value]) {
      acc[value] = [];
    }
    acc[value].push(user);
    return acc;
  }, {});
}

5.1.4 主程序

// src/main.js
import { User } from './models/User.js';
import { filterActiveUsers, groupBy } from './utils/arrayUtils.js';

const users = [
  new User(1, 'Alice', 'alice@example.com', 'admin', true),
  new User(2, 'Bob', 'bob@example.com', 'user', false),
  new User(3, 'Charlie', 'charlie@example.com', 'admin', true)
];

const activeUsers = filterActiveUsers(users);
const roleGroups = groupBy(activeUsers, 'role');

console.log(roleGroups);
// 输出: { admin: [User 1], user: [User 2] }

六、源码解析

6.1 构造函数的原型链

function Person() {}
Person.prototype = {
  constructor: Person,
  sayHi: function() { console.log("Hi"); }
};

const p = new Person();
console.log(p.__proto__ === Person.prototype); // true

6.2 闭包的内存管理

function createCounter() {
  let count = 0;
  return {
    increment: () => count++,
    getCount: () => count
  };
}

const counter = createCounter();
console.log(counter.getCount()); // 0
counter.increment();
console.log(counter.getCount()); // 1

6.3 数组的内存优化

function optimizeArray(arr) {
  const result = new Array(arr.length);
  for (let i = 0; i < arr.length; i++) {
    result[i] = arr[i];
  }
  return result;
}

七、进阶使用

7.1 精确继承实现

function inherit(target, source) {
  Object.keys(source).forEach(key => {
    target[key] = source[key];
  });
}

7.2 高阶函数组合

function compose(...fns) {
  return function (value) {
    return fns.reduceRight((acc, fn) => fn(acc), value);
  };
}

const double = x => x * 2;
const addOne = x => x + 1;
const composed = compose(double, addOne);
console.log(composed(3)); // 8

7.3 数组的内存优化策略

function optimizedArray() {
  const arr = new Array(1000000);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = i;
  }
  return arr;
}

八、性能与工程实践

8.1 数组性能优化

  • 使用Array.from代替new Array
  • 避免使用delete操作符
  • 使用TypedArray处理二进制数据

8.2 函数的内存管理

  • 避免不必要的闭包
  • 使用WeakMap处理弱引用
  • 使用Symbol作为私有属性

8.3 对象的性能优化

  • 使用Object.freeze防止修改
  • 使用Proxy进行属性拦截
  • 避免频繁修改原型链

九、常见问题与踩坑

9.1 常见错误

9.1.1 原型链污染

Object.prototype.__proto__ = { evil: true };

9.1.2 闭包内存泄漏

function createClosure() {
  const data = [1, 2, 3];
  return () => console.log(data);
}

9.1.3 数组方法副作用

const arr = [1, 2, 3];
arr.map(x => x * 2).forEach(console.log); // [2, 4, 6]

9.2 解决方案

9.2.1 原型链污染防护

Object.defineProperty(Object.prototype, '__proto__', {
  writable: false,
  configurable: false
});

9.2.2 闭包内存优化

function createClosure() {
  const data = [1, 2, 3];
  return () => {
    const copy = data.slice();
    console.log(copy);
  };
}

9.2.3 数组方法安全使用

const arr = [1, 2, 3];
const result = arr.map(x => x * 2);
console.log(result); // [2, 4, 6]

十、最佳实践

10.1 对象使用规范

场景推荐方案原因
需要继承ES6类更清晰的结构
需要动态属性Object.assign灵活的属性合并
避免污染禁用原型链防止意外覆盖

10.2 函数使用规范

场景推荐方案原因
需要闭包使用箭头函数简化this绑定
需要高阶函数使用函数式编程提高可读性
需要安全调用使用Optional Chaining避免空指针

10.3 数组使用规范

场景推荐方案原因
需要性能使用TypedArray更高效的内存管理
需要精确拷贝使用JSON.parse/JSON.stringify简单的深拷贝
需要内存优化使用Array.from更高效的内存分配

十一、总结

JavaScript的对象、函数和数组是构建现代Web应用的基石。理解它们的底层机制和使用规范,是编写高质量代码的关键。在实际开发中,需要根据具体场景选择合适的实现方式:对象用于封装数据和行为,函数用于封装逻辑,数组用于处理集合数据。通过合理使用闭包、原型链、数组方法等技术,可以构建出高效、可维护的代码。同时,要警惕常见的性能陷阱和安全风险,采用最佳实践来保证代码的健壮性。

最后修改于:2026年09月14日 16:48

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日