从生活场景学透 JavaScript 原型与原型链

一、构造函数:以 "人" 为例的对象工厂

1. 生活场景下的构造函数定义

我们以 "人" 为场景创建构造函数,每个人都有姓名、年龄等个性化属性,也有人类共有的特征:

javascript 复制代码
// 人类构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
  // 每个人独特的属性
  this.hobby = `喜欢 ${name}的爱好`;
}

// 创建两个人的实例
const person1 = new Person("小明", 20);
const person2 = new Person("小红", 22);

console.log(person1); // Person { name: '小明', age: 20, hobby: '喜欢小明的爱好' }
console.log(person2); // Person { name: '小红', age: 22, hobby: '喜欢小红的爱好' }

2. 基础数据类型的生活类比

以 "水果" 为例理解基础数据类型的两种定义方式:

javascript 复制代码
// 定义水果的两种方式
let fruit1 = "苹果"; // 字面量方式
let fruit2 = new String("香蕉"); // 构造函数方式

console.log(fruit1); // 苹果
console.log(fruit2); // 香蕉

二、原型(prototype):提取人类共同特征

1. 提取人类共同属性到原型

人类共有的属性(如物种、默认行为)适合放在原型上:

javascript 复制代码
// 优化:将人类共同属性放到原型上
Person.prototype.species = "智人";
Person.prototype.gender = "默认未知";
Person.prototype.speak = function() {
  return `${this.name}说:你好!`;
};

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.hobby = `喜欢 ${name}的爱好`;
}

const person1 = new Person("小明", 20);
const person2 = new Person("小红", 22);

// 访问原型上的属性
console.log(person1.species); // 智人
console.log(person2.speak()); // 小红说:你好!
console.log(person1); // Person { name: '小明', age: 20, hobby: '喜欢小明的爱好' }

2. 原型属性的不可修改性演示

尝试修改原型属性,观察实例的变化:

javascript 复制代码
// 原型属性不可修改的演示
Person.prototype.species = "智人";
Person.prototype.speak = function() {
  return `${this.name}说:你好!`;
};

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

const person = new Person("小明", 20);

console.log(person.species); // 智人
// 尝试修改原型属性
person.species = "外星人";
console.log(person.species); // 外星人(实例自身添加了属性)
console.log(Person.prototype.species); // 智人(原型属性未改变)

三、对象原型(proto):隐式链接的生活比喻

1. 隐式原型的链接关系

以 "动物" 为例说明隐式原型的指向关系:

javascript 复制代码
// 动物构造函数
function Animal() {}
Animal.prototype.eat = function() {
  return "正在进食";
};

// 狗构造函数
function Dog(name) {
  this.name = name;
}
// 狗的原型指向动物的原型
Dog.prototype = new Animal();

const dog = new Dog("旺财");

// 验证隐式原型关系
console.log(dog.__proto__ === Dog.prototype); // true
console.log(Dog.prototype.__proto__ === Animal.prototype); // true
console.log(dog.eat()); // 正在进食(通过原型链调用)

2. 隐式原型的查找机制

通过 "学生" 对象演示属性查找过程:

javascript 复制代码
// 学生构造函数
function Student(name) {
  this.name = name;
}

// 学生原型添加属性
Student.prototype.school = "默认学校";
Student.prototype.study = function() {
  return `${this.name}在学习`;
};

const student = new Student("小李");

// 查找属性的过程
console.log(student.name); // 小李(自身属性)
console.log(student.school); // 默认学校(原型属性)
console.log(student.study()); // 小李在学习(原型方法)

四、this 的原理:从 "创建房屋" 理解 new 操作

1. 房屋构造函数中的 this

模拟房屋建造过程,理解 this 在构造函数中的作用:

javascript 复制代码
// 房屋构造函数
function House(owner, area) {
  this.owner = owner;
  this.area = area;
  this.roomCount = 3; // 默认3个房间

  // 这里隐含了new的执行过程
  // 1. 创建空对象 obj = {}
  // 2. this指向obj
  // 3. 执行属性赋值
  // 4. obj.__proto__ = House.prototype
  // 5. 返回obj
}

House.prototype.address = "未知地址";
House.prototype.showInfo = function() {
  return `${this.owner}的房子,面积 ${this.area}㎡,位于 ${this.address}`;
};

const myHouse = new House("张三", 120);
console.log(myHouse.showInfo()); // 张三的房子,面积120㎡,位于未知地址

五、原型链:从 "交通工具" 看对象继承关系

1. 交通工具的原型链结构

通过交通工具的层级关系展示原型链:

javascript 复制代码
// 交通工具基类
function Vehicle() {
  this.type = "交通工具";
}
Vehicle.prototype.move = function() {
  return "正在移动";
};

// 汽车类
function Car(brand) {
  this.brand = brand;
}
Car.prototype = new Vehicle();
Car.prototype.drive = function() {
  return `${this.brand}汽车在行驶`;
};

// 电动车类
function ElectricCar(brand, battery) {
  Car.call(this, brand);
  this.battery = battery;
}
ElectricCar.prototype = new Car("默认品牌");
ElectricCar.prototype.charge = function() {
  return `正在给 ${this.brand}电动车充电`;
};

// 创建电动车实例
const car = new ElectricCar("特斯拉", "锂电池");

// 原型链查找演示
console.log(car.brand); // 特斯拉(自身属性)
console.log(car.drive()); // 特斯拉汽车在行驶(Car原型方法)
console.log(car.move()); // 正在移动(Vehicle原型方法)
console.log(car.charge()); // 正在给特斯拉电动车充电(自身方法)

2. 原型链的根对象演示

通过 Object.create 创建特殊对象:

javascript 复制代码
// 普通对象
const normalObj = new Object();
console.log(normalObj.__proto__); // Object.prototype

// 使用Object.create创建无原型的对象
const specialObj = Object.create(null);
console.log(specialObj.__proto__); // undefined

// 验证原型链终点
console.log(Object.prototype.__proto__); // null

六、生活场景总结表

概念 生活类比 代码
构造函数 工厂生产线 首字母大写,用 new 创建实例
原型 (prototype) 人类共同特征手册 存放同类对象的公共属性和方法
隐式原型 (proto) 家族族谱 实例指向构造函数的原型
原型链 生物进化树 多层继承关系形成的属性查找链路
this 工厂中的施工图纸 指向新创建的对象实例
相关推荐
AI大模型17 小时前
前端学 AI 不用愁!手把手教你用 LangGraph 实现 ReAct 智能体(附完整流程 + 代码)
前端·llm·agent
小红17 小时前
网络通信基石:从IP地址到子网划分的完整指南
前端·网络协议
一枚前端小能手17 小时前
🔥 前端储存这点事 - 5个存储方案让你的数据管理更优雅
前端·javascript
willlzq17 小时前
深入探索Swift的Subscript机制和最佳实践
前端
RockerLau17 小时前
micro-zoe子应用路由路径污染问题
前端
代码代码快快显灵17 小时前
Axios的基本知识点以及vue的开发工程(基于大事件)详细解释
前端·javascript·vue.js
文心快码BaiduComate17 小时前
再获殊荣!文心快码荣膺2025年度优秀软件产品!
前端·后端·代码规范
Mintopia18 小时前
🚀 Next.js 后端能力扩展:错误处理与 HTTP 状态码规范
前端·javascript·next.js
IT酷盖18 小时前
Android解决隐藏依赖冲突
android·前端·vue.js
mwq3012318 小时前
RNN 梯度计算详细推导 (BPTT)
前端