深入理解JavaScript构造函数与原型链:从原理到最佳实践

news2025/3/14 22:44:09

一、开篇:为什么需要理解原型链?

在JavaScript开发中,90%以上的"诡异"bug都与原型链机制相关。理解构造函数与原型链的运行原理,不仅能帮助我们写出更优雅的代码,还能在框架源码阅读、性能优化等场景中游刃有余。本文将通过全新视角,带你系统掌握这一核心机制。

二、构造函数:对象创建的基石

2.1 构造函数基础

function User(name) {
  this.name = name
  this.login = function() {
    console.log(`${this.name} logged in`)
  }
}

const user1 = new User('Alice')
const user2 = new User('Bob')

这种传统方式存在明显问题:每个实例都会创建新的login方法,造成内存浪费。

2.2 new操作符的魔法

当使用new调用函数时,JS引擎会执行以下步骤:

  1. 创建空对象 {}
  2. 设置原型链接:obj.__proto__ = Constructor.prototype
  3. 绑定this并执行构造函数
  4. 自动返回新对象(除非构造函数返回对象)

三、原型对象:共享的智慧

3.1 原型方法优化

function User(name) {
  this.name = name
}

User.prototype.login = function() {
  console.log(`${this.name} logged in`)
}

此时所有User实例共享同一个login方法,内存效率提升100倍(实测10,000个实例可节省约1.5MB内存)。

3.2 原型链查找机制

访问对象属性时,JS引擎会:

  1. 检查实例自身属性
  2. 沿__proto__链向上查找
  3. 直到Object.prototype为止(终点为null)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-URxwgDf1-1741881116173)(https://via.placeholder.com/600x300/EEE/000?text=Prototype+Chain+Diagram)]

四、进阶原型操作

4.1 原型继承的三种方式

// 1. 构造函数继承
function Admin(...args) {
  User.apply(this, args)
}

// 2. 原型链继承
Admin.prototype = Object.create(User.prototype)

// 3. 组合继承(最优)
function Admin(...args) {
  User.apply(this, args)
}
Admin.prototype = Object.create(User.prototype)
Admin.prototype.constructor = Admin

4.2 ES6 class语法糖

class User {
  constructor(name) {
    this.name = name
  }

  login() {
    console.log(`${this.name} logged in`)
  }
}

class Admin extends User {
  constructor(name, level) {
    super(name)
    this.level = level
  }
}

Babel转译后的代码显示,class本质仍是基于原型链的实现。

五、性能优化实践

5.1 原型方法 vs 实例方法

方式内存占用访问速度适用场景
原型方法稍慢通用方法
实例方法需要闭包/私有变量的方法

5.2 原型污染防护

// 冻结原型防止修改
Object.freeze(User.prototype)

// 使用无原型对象
const safeObj = Object.create(null)

六、常见问题解析

6.1 原型链关系判断

// 正确方式
console.log(user1 instanceof User) // true
console.log(User.prototype.isPrototypeOf(user1)) // true

// 错误方式
console.log(user1.__proto__ === User.prototype) // 不推荐直接访问__proto__

6.2 箭头函数陷阱

function User() {
  this.name = 'test'
  this.getName = () => this.name // 箭头函数没有prototype
}

const u = new User()
console.log(u.hasOwnProperty('getName')) // true

七、现代开发最佳实践

  1. 优先使用class语法,保持代码可读性
  2. 复杂对象方法使用原型存储
  3. 避免超过3层的原型继承
  4. 使用组合模式代替深度继承
  5. 利用WeakMap实现真正私有属性

八、从框架看原型应用

  • Vue组件系统:每个组件都是Vue基类的扩展
  • React类组件:通过继承React.Component获得生命周期方法
  • Express中间件:通过原型链实现功能扩展

九、总结与思考

理解原型链机制是成为JavaScript高手的必经之路。通过本文的学习,我们不仅掌握了原型链的运作原理,更学会了如何在现代开发中合理运用这一特性。下次当你遇到undefined is not a function错误时,不妨先检查原型链的指向是否正确。

思考题:如何实现一个可以撤销修改的原型链系统?欢迎在评论区分享你的方案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2315114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux 指北】常用 Linux 指令汇总

第一章、常用基本指令 # 注意: # #表示管理员 # $表示普通用户 [rootlocalhost Practice]# 说明此处表示管理员01. ls 指令 语法: ls [选项][目录或文件] 功能:对于目录,该命令列出该目录下的所有子目录与文件。对于文件&#xf…

docker 搭建alpine下nginx1.26/mysql8.0/php7.4环境

docker 搭建alpine下nginx1.26/mysql8.0/php7.4环境 docker-compose.yml services:mysql-8.0:container_name: mysql-8.0image: mysql:8.0restart: always#ports:#- "3306:3306"volumes:- ./etc/mysql/conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro- ./var/log…

Android7上移植I2C-tools

一,下载源码 cd hardware/libhardware/tests git clone https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git 二, 在 i2c-tools 目录添加 Android.mk 编译文件 LOCAL_PATH: $(call my-dir)################### i2c-tools ###############…

Centos 7 修改语言和输入源为中文+修改终端快捷键复制为Ctrl+C、粘贴为Ctrl+V

目录 修改语言和输入源为中文 1、设置 2、Region & Language(区域和语言) 3、Add an Input Source(添加输入源) 4、修改语言为中文 5、Restart(重启) 6、Log Out (注销) …

DeepSeek-进阶版部署(Linux+GPU)

前面几个小节讲解的Win和Linux部署DeepSeek的比较简单的方法,而且采用的模型也是最小的,作为测试体验使用是没问题的。如果要在生产环境使用还是需要用到GPU来实现,下面我将以有一台带上GPU显卡的Linux机器来部署DeepSeek。这里还只是先体验单…

Python——计算机网络

一.ip 1.ip的定义 IP是“Internet Protocol”的缩写,即“互联网协议”。它是用于计算机网络通信的基础协议之一,属于TCP/IP协议族中的网络层协议。IP协议的主要功能是负责将数据包从源主机传输到目标主机,并确保数据能够在复杂的网络环境中正…

一招解决Pytorch GPU版本安装慢的问题

Pytorch是一个流行的深度学习框架,广泛应用于计算机视觉、自然语言处理等领域。安装Pytorch GPU版本可以充分利用GPU的并行计算能力,加速模型的训练和推理过程。接下来,我们将详细介绍如何在Windows操作系统上安装Pytorch GPU版本。 查看是否…

框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性

最近在思考一个问题:如何能够更好的分享主流框架源码学习笔记(主要是源码部分)?让有缘刷到的同学既可以有所收获,还能保持对相关技术架构探讨学习热情和兴趣。以及自己也保持较高的分享热情和动力。 今天尝试用一个SQL查询作为引…

ArrayList底层结构和源码分析笔记

参考视频:韩顺平Java集合 ArrayList特点 ArrayList 可以加入 null,包括多个。 ArrayList 是由数组来实现数据存储的 ArrayList 基本等同于 Vector,除了 ArrayList 是线程不安全(执行效率高)。在多线程情况下&#xf…

[内网渗透] 红日靶场2

环境配置 靶场地址: http://vulnstack.qiyuanxuetang.net/vuln/wiki/ 环境配置可以看这个: https://www.bilibili.com/video/BV1De4y1a7Ps/?spm_id_from333.337.search-card.all.click&vd_sourcecf73ac8de9b7c0322b1bccf77de91c5dNAT模式分配111段, DHCP也要更改 再添加…

MySQL 企业版 TDE加密后 测试和问题汇总

一、测试keyring file 1.1 当keyring file文件丢失或者被篡改 结论:不影响当前正在运行的数据库,但是在重启服务后会启动失败出现报错。 tail -n 100 /var/log/mysql/error.log 报错信息如下: 2025-03-12T08:04:54.668847Z 1 [ERROR] [M…

Unity 封装一个依赖于MonoBehaviour的计时器(下) 链式调用

[Unity] 封装一个依赖于MonoBehaviour的计时器(上)-CSDN博客 目录 1.加入等待间隔时间"永远执行方法 2.修改为支持链式调用 实现链式调用 管理"链式"调度顺序 3.测试 即时方法​编辑 "永久"方法 链式调用 ​4.总结 1.加入等待间隔时间&qu…

套接字缓冲区以及Net_device

基础网络模型图 一般网络设计分为三层架构和五层设计: 一、三层架构 用户空间的应用层 位于最上层,是用户直接使用的网络应用程序,如浏览器、邮件客户端、即时通讯软件等。这些程序通过系统调用(如 socket 接口)向内核…

2024下半年真题 系统架构设计师 案例分析

案例一 软件架构 关于人工智能系统的需求分析,给出十几个需求。 a.系统发生业务故障时,3秒内启动 XXX,属于可靠性 b.系统中的数据进行导出,要求在3秒内完成,属于可用性 c.质量属性描述,XXX,属…

c++介绍智能指针 十二(2)

智能指针share_ptr,与unique_ptr不同&#xff0c;多个shar_ptr对象可以共同管理一个指针&#xff0c;它们通过一个共同的引用计数器来管理指针。当一个智能指针对象销毁时&#xff0c;计数器减一。当计数器为0时&#xff0c;会将所指向的内存对象释放。 #include<memory>…

西门子S7-1200 PLC远程调试技术方案(巨控GRM532模块)

三步快速实现远程调试 硬件部署 准备西门子S7-1200 PLC、巨控GRM552YW-C模块及编程电脑。GRM552YW-C通过网口与PLC连接&#xff0c;支持4G/5G/Wi-Fi/有线网络接入&#xff0c;无需复杂布线。 软件配置 安装GVCOM3配置软件&#xff0c;注册模块&#xff08;输入唯一序列号与密…

Mac上更改默认应用程序

Mac上为某些文件设置默认打开应用的时候&#xff0c;刚开始是通过打开方式&#xff0c;其他里面&#xff0c;勾选始终以此方式打开&#xff0c;但实际上这个功能并不太好用&#xff0c;经常会让人误以为已经设置好了。但是实际上只是在当前目录起作用。真正解决这个问题可以按照…

【开源+代码解读】Search-R1:基于强化学习的检索增强大语言模型框架3小时即可打造个人AI-search

大语言模型(LLMs)在处理复杂推理和实时信息检索时面临两大挑战:知识局限性(无法获取最新外部知识)和检索灵活性不足(传统方法依赖固定检索流程)。现有方法如检索增强生成(RAG)和工具调用(Tool-Use)存在以下问题: RAG:单轮检索导致上下文不足,无法适应多轮交互场景…

贪心算法和遗传算法优劣对比——c#

项目背景&#xff1a;某钢管厂的钢筋原材料为 55米&#xff0c;工作需要需切割 40 米&#xff08;1段&#xff09;、11 米&#xff08;15 段&#xff09;等 4 种规格 &#xff0c;现用贪心算法和遗传算法两种算法进行计算&#xff1a; 第一局&#xff1a;{ 40, 1 }, { 11, 15…

网络安全防护总体架构 网络安全防护工作机制

1 实践内容 1.1 安全防范 为了保障"信息安全金三角"的CIA属性、即机密性、完整性、可用性&#xff0c;信息安全领域提出了一系列安全模型。其中动态可适应网络安全模型基于闭环控制理论&#xff0c;典型的有PDR和P^2DR模型。 1.1.1 PDR模型 信息系统的防御机制能…