当前位置: 首页 > news >正文

JavaScript进阶篇——第七章 原型与构造函数核心知识

目录

1. 构造函数基础

2. 原型对象(prototype)

3. constructor 属性

4. 对象原型(proto)

5. 原型链机制

6. 复习要点速查表


本文系统讲解了JavaScript构造函数与原型机制。要点包括:1)构造函数封装实例属性和方法,但会造成方法重复创建;2)通过prototype原型对象实现方法共享,节约内存;3)constructor属性保持原型与构造函数的关联;4)proto__形成原型链,实现方法查找机制;5)完整原型链结构为实例→构造函数原型→Object原型→null。最佳实践是将方法定义在原型上、属性放在构造函数中,避免直接使用__proto,重写原型时需修复constructor指向。原型系统通过三大关系(构造函数-原型-实例)实现面向对象特性,有效解决内存浪费问题。

1. 构造函数基础

1.1 封装特性

构造函数是实现面向对象封装的核心工具

// ✅ 构造函数封装数据和方法
function Star(uname, age) {this.uname = uname;this.age = age;this.sing = function() {console.log('我会唱歌');}
}// 创建实例对象
const ldh = new Star('刘德华', 18);
const zxy = new Star('张学友', 19);ldh.sing(); // "我会唱歌"
zxy.sing(); // "我会唱歌"// ❗ 重点:实例对象彼此独立,互不影响
ldh.age = 20;
console.log(zxy.age); // 19(不受影响)

1.2 内存浪费问题

// ⚠️ 问题:每个实例都创建自己的方法副本
console.log(ldh.sing === zxy.sing); // false// 内存结构图示:
// | 实例1 | → | sing方法1 |
// | 实例2 | → | sing方法2 |
// 相同功能的方法被重复创建,浪费内存

2. 原型对象(prototype)

2.1 原型是什么

每个构造函数都有一个prototype属性,指向原型对象

function Star(uname, age) {this.uname = uname;this.age = age;
}// ✅ 访问构造函数的原型对象
console.log(Star.prototype); // 原型对象(最初为空)// ✅ 在原型上添加共享方法
Star.prototype.sing = function() {console.log('我会唱歌');
}const ldh = new Star('刘德华', 18);
const zxy = new Star('张学友', 19);// 验证方法共享
console.log(ldh.sing === zxy.sing); // true(共享同一个方法)

2.2 原型的作用

  1. 共享方法:所有实例共享原型上的方法

  2. 节约内存:方法只创建一次,所有实例共用

  3. 扩展功能:可随时向原型添加新方法

2.3 this指向

构造函数和原型方法中的this都指向实例对象

let that;
function Person(name) {this.name = name;that = this; // this指向即将创建的实例
}const o = new Person('小明');
console.log(that === o); // true// 原型方法中的this
Person.prototype.sayHello = function() {console.log(`你好,我是${this.name}`);
}o.sayHello(); // "你好,我是小明"

3. constructor 属性

3.1 作用与位置

每个原型对象都有constructor属性,指向关联的构造函数

function Star(name) {this.name = name;
}console.log(Star.prototype.constructor === Star); // trueconst ldh = new Star('刘德华');
console.log(ldh.constructor === Star); // true

3.2 使用场景

当重写整个原型对象时,需要手动设置constructor

function Star(name) {this.name = name;
}// ❌ 错误写法:重写原型会丢失constructor
Star.prototype = {sing: function() {console.log("唱歌");},dance: function() {console.log("跳舞");}
};
console.log(Star.prototype.constructor); // 指向Object(错误)// ✅ 正确写法:手动添加constructor
Star.prototype = {constructor: Star, // 修复constructor指向sing: function() {console.log("唱歌");},dance: function() {console.log("跳舞");}
};
console.log(Star.prototype.constructor === Star); // true

4. 对象原型(proto

4.1 作用与原理

每个实例对象都有__proto__属性,指向构造函数的原型对象

function Star(name) {this.name = name;
}const ldh = new Star('刘德华');// 对象原型关系
console.log(ldh.__proto__ === Star.prototype); // true
console.log(ldh.__proto__.constructor === Star); // true

4.2 原型链机制

// 原型链查找过程:
// 1. 访问ldh.sing()
// 2. 先在ldh实例上查找 → 未找到
// 3. 通过ldh.__proto__找到Star.prototype
// 4. 在Star.prototype上找到sing方法并执行// ❗ 重点:这就是为什么实例能访问原型上的方法

4.3 注意事项

  1. __proto__是非标准属性(实际开发中避免直接使用)

  2. 标准属性是[[Prototype]],与__proto__意义相同

  3. 可以使用Object.getPrototypeOf()获取原型

  4. __proto__对象原型里也有constructor属性

// 推荐:使用标准方法获取原型
console.log(Object.getPrototypeOf(ldh) === Star.prototype); // true

5. 原型链机制

5.1 完整原型链

text实例对象 (ldh)↓ __proto__
构造函数原型 (Star.prototype)↓ __proto__
Object原型 (Object.prototype)↓ __proto__
null

5.2 原型链验证

function Star() {}
const ldh = new Star();// 验证原型链
console.log(ldh.__proto__ === Star.prototype); // true
console.log(Star.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null

6. 复习要点速查表

核心概念关系

概念位置指向作用
prototype构造函数上原型对象存放共享方法
proto实例对象上构造函数的prototype实现原型链查找
constructor原型对象上构造函数表明原型对象的来源

原型系统三大关系

  1. 构造函数 ↔ 原型对象
    构造函数.prototype = 原型对象
    原型对象.constructor = 构造函数

  2. 实例对象 ↔ 原型对象
    实例对象.__proto__ = 构造函数.prototype

  3. 原型对象 ↔ Object原型
    构造函数.prototype.__proto__ = Object.prototype

高频面试题解答

  1. prototype是什么?
    构造函数自动拥有的原型对象,用于存放共享方法

  2. constructor属性在哪里?
    存在于原型对象和对象原型中,指向创建它们的构造函数

  3. __proto__属性在哪里?指向谁?
    在每个实例对象中,指向构造函数的原型对象

  4. 如何解决构造函数的内存浪费问题?
    将方法定义在原型对象上,实现方法共享

  5. 原型链的终点是什么?
    null(Object.prototype.proto === null)

最佳实践

  1. 方法放在原型上:节约内存,实现共享

  2. 属性放在构造函数中:保持实例独立性

  3. 避免直接使用__proto__:使用Object.getPrototypeOf()

  4. 重写原型时修复constructor:保持正确的构造函数指向

// ✅ 推荐模式
function Person(name) {// 实例属性this.name = name;
}// 原型方法
Person.prototype.sayHello = function() {console.log(`你好,我是${this.name}`);
};// 创建实例
const p = new Person('小明');
p.sayHello();

记忆口诀
"构造函数造实例,prototype存共享"
"__proto__连原型,constructor指根源"
"原型链上找方法,层层查找不迷路"
"方法共享省内存,面向对象真强大"

http://www.dtcms.com/a/283946.html

相关文章:

  • 深度学习 -- 初步认识Torch
  • vue中的this.$set
  • 在分布式系统中,如何保证缓存与数据库的数据一致性?
  • LVS实验
  • 板凳-------Mysql cookbook学习 (十一--------12)
  • LVS集群
  • Docker实战:使用Docker部署IT工具箱Team·IDE
  • Android15系统实现刷机防呆功能
  • Flutter在Android studio运行出现Error: Entrypoint is not a Dart file
  • C++网络编程 2.TCP套接字(socket)编程详解
  • 微信小程序列表数据上拉加载,下拉刷新
  • ASP .NET Core 8实现实时Web功能
  • Python 网络爬虫 —— 提交信息到网页
  • AI算法之图像识别与分类
  • 电力载波通信技术(PLC)发展全解析:从历史演进到未来趋势
  • RabbitMQ概述和工作模式
  • 永磁同步电机MTPA与MTPV曲线具体仿真实现
  • Python学习之——序列化与反序列化
  • 常用的100个opencv函数
  • [RAG] LLM 交互层 | 适配器模式 | 文档解析器(`docling`库, CNN, OCR, OpenCV)
  • 加速度传感器方向校准方法
  • RGBA图片格式转换为RGB格式(解决convert转换的失真问题)
  • OpenCV中VideoCapture 设置和获取摄像头参数和Qt设计UI控制界面详解代码示例
  • (四)OpenCV——特征点检测与匹配
  • 分布式分片策略中,分片数量的评估与选择
  • MacOS安装linux虚拟机
  • GPU的barrier
  • OpenCV中常用特征提取算法(SURF、ORB、SIFT和AKAZE)用法示例(C++和Python)
  • Linux的Ext系列文件系统
  • 一文掌握Harbor的配额管理和GC机制