面试复盘:谈谈你对 原型、原型链、构造函数、实例、继承的理解

谈谈你对 原型、原型链、构造函数、实例、继承的理解

构造函数(constuctors):为了批量创建对象,我们会用首字母大写的函数来定义构造函数,functon Person(name,age){ this.name = name;this.age = age; }

实例(instances):通过构造函数创建的对象,就是该构造函数的实例 let xiaoming = new Person("小明",18);

new 关键字做了什么:

kotlin 复制代码
使用 new 调用时会做四件事:
创建一个空对象
把这个空对象的 __proto__ 指向构造函数的 prototype
把函数中的 this 指向这个新对象
执行函数体代码(给 this 加属性)
返回这个对象(除非手动返回其他对象)

原型(prototype):每一个构造函数身上会有一个prototype属性,这个属性指向一个对象,这个对象就是我们说的原型对象。

原型链:Preson.prototype == xiaoming.proto

markdown 复制代码
注意:
1、xiaoming 本身没有 .constructor 属性,它是顺着原型链在 xiaoming.__proto__(即 Person.prototype)上找到的。所以 xiaoming.constructor 实际上指向了 Person。
2、"__proto__ 是构造函数的属性"	         ❌ __proto__ 是**实例**的属性
3、"prototype 是所有对象都有"	         ❌ 只有函数有 prototype(箭头函数除外)
4、"constructor 一定是可靠的"	         ❌ 如果原型被替换过(如继承中),必须手动修复
5、"原型链是从 prototype 到 prototype"	 ❌ 是从 __proto__ 到 __proto__ 的链

原型链查找:

javascript 复制代码
当你访问 xiaoming.sayHello 时,引擎会:
查自身属性:首先检查 xiaoming 对象本身是否有 sayHello 属性。
沿链向上:如果没有,就通过 xiaoming.__proto__ 找到 Person.prototype,看这里有没有。
继续向上:如果还没有,就继续通过 Person.prototype.__proto__ 找到 Object.prototype(因为所有对象默认原型链的顶端都是它)。
直到终点:如果 Object.prototype 上还没有,就再通过 Object.prototype.__proto__ 找到 null,然后返回 undefined。

最终一句话总结
当你访问一个对象的属性或方法时,如果它自己没有,JS 就会顺着它的 __proto__ 往上找,一直找到 Object.prototype,再找不到就返回 undefined ------ 这个查找路径,就是**原型链**。

而这一切的基础是:

实例.__proto__ === 构造函数.prototype

es5的继承:

javascript 复制代码
// 父类构造函数
function Animal(name) {
    this.name = name;
    this.type = 'animal';
}

// 父类方法放在原型上
Animal.prototype.eat = function() {
    console.log(this.name + " 在吃东西");
};

// 子类构造函数
function Dog(name, breed) {
    // ✅ 构造函数继承:借用父类构造函数
    Animal.call(this, name);  // 继承实例属性:name, type
    this.breed = breed;       // 子类特有属性
}

// ✅ 原型链继承:建立原型关系
Dog.prototype = Object.create(Animal.prototype);
创建了一个新的空对象
将这个新对象的 __proto__ 指向 Animal.prototype
将这个新对象赋值给 Dog.prototype
这样就建立了正确的原型链关系:

dog 实例对象 
↓ __proto__ 
Dog.prototype (新创建的对象)
↓ __proto__ 
Animal.prototype 
↓ __proto__ 
Object.prototype 
↓ __proto__ 
null

// 注意:不能直接 Dog.prototype = new Animal()
Dog 和 Animal 会共享同一个原型对象
在 Dog.prototype 上添加方法也会影响到 Animal.prototype
Animal 的实例也会获得 Dog 特有的方法,这显然不符合继承的设计意图

// 修正 constructor 指向
Dog.prototype.constructor = Dog;
// 因为 Object.create(Animal.prototype) 创建的新对象的 constructor 属性会指向 Animal,而不是 Dog。修正后才能保证
// 因为 Dog.prototype 被重新赋值了,原来的 constructor 丢了。
// 不修复的话:dog.constructor === Animal ❌
// 修复后:dog.constructor === Dog ✅

// 子类自己添加方法
Dog.prototype.bark = function() {
    console.log(this.name + " 在汪汪叫");
};

// 使用
const dog = new Dog("旺财", "哈士奇");
dog.eat();  // ✅ 调用父类方法 → "旺财 在吃东西"
dog.bark(); // ✅ 调用自己的方法 → "旺财 在汪汪叫"
console.log(dog.type); // ✅ "animal",来自 Animal 构造函数

总结:组合继承的核心步骤
步骤	目的	写法
1️⃣ 构造函数继承	继承父类的实例属性	Animal.call(this, ...)
2️⃣ 原型链继承	继承父类的原型方法	Dog.prototype = Object.create(Animal.prototype)
3️⃣ 修复 constructor	保持 constructor 正确	Dog.prototype.constructor = Dog

ES6 class继承(现代标准)

scala 复制代码
class Parent {
  constructor(name) { this.name = name; }
  say() { console.log(this.name); }
}

class Child extends Parent { // 核心: extends
  constructor(name, age) {
    super(name); // 核心: super 调用父类构造函数
    this.age = age;
  }
}

let c = new Child('Tom', 10);
c.say(); // 'Tom'
相关推荐
柳杉38 分钟前
用 GPT-6 Astra 和 Tripo3D 做智慧农业 3D 大屏:从调研到可巡检园区全流程实录
前端·ai编程·数据可视化
特创数字科技43 分钟前
【uni-app x】告别系统相机限制!三端通用自定义相机组件:任意布局、静默拍照、录像、水印叠加、连拍回图一次搞定
前端·数码相机·uni-app
IT_陈寒1 小时前
用Vue时这个响应式陷阱坑了我一整天
前端·人工智能·后端
风骏时光牛马1 小时前
企业客户信息管理数据库
前端
paopaokaka_luck1 小时前
个人综合管理小程序(echarts数据看板、健康数据记录与趋势查看、目标拆解和进度管理、日程待办与番茄钟、习惯打卡、收支统计、个人生活记录、跨模块智能提醒)
前端·javascript·spring·小程序·数据分析·echarts·生活
霸道流氓气质1 小时前
Graph Studio Web IDE 深度实战:可视化编排、断点调试与生产级运维全指南
运维·前端·ide
福兮说9 小时前
前端下载大文件,点了按钮半天没反应:fetch + blob 的三个问题和三种替代写法
前端·javascript·性能优化·文件下载
GreenTea9 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
科技观察哨10 小时前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能