从生活场景学透 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 工厂中的施工图纸 指向新创建的对象实例
相关推荐
阿祖zu几秒前
2026 企业级 Agent 产品落地思考与全流程指南
前端·程序员·aigc
yqcoder17 分钟前
拆解互联网:通俗易懂的网络分层模型
前端·网络·网络协议
小鹿软件办公24 分钟前
Mozilla 解释 Firefox 在英特尔 Raptor Lake 系统上的崩溃问题
前端·firefox
代码熊崽的编程森林27 分钟前
vue + onlyoffice 自定义插件的实现(OnlyOffice 插件:AI 智能编辑)。
前端·javascript·vue.js
Lucky_Turtle1 小时前
【Vue】element plus Slider小数组件设置顺滑程度
前端·javascript·vue.js
Bigger1 小时前
🔥 一份 Agent 工程岗 JD,暴露了市场真正想要什么样的人
前端·agent·全栈
我头上有犄角ovo1 小时前
我在微信小程序里手搓人脸识别引导,结果被“右转头”和“手遮脸”教育了
前端
David_Xia1 小时前
干爆 11s 提交卡顿!引入 Rust 级 oxlint 彻底拯救团队 Git Commit 噩梦的重构实践
前端
前端环境观察室1 小时前
别急着让 Agent 跑任务,先把浏览器环境上下文建模
前端
Dxy12393102161 小时前
js中Math.min.apply()详解
开发语言·javascript