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

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

构造函数(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'
相关推荐
Aniugel3 小时前
单点登录(SSO)系统
前端
颜酱3 小时前
二叉树遍历思维实战
javascript·后端·算法
鹏多多3 小时前
移动端H5项目,还需要react-fastclick解决300ms点击延迟吗?
前端·javascript·react.js
serioyaoyao3 小时前
上万级文件一起可视化,怎么办?答案是基于 ParaView 的远程可视化
前端
万少3 小时前
端云一体 一天开发的元服务-奇趣故事匣经验分享
前端·ai编程·harmonyos
WindrunnerMax3 小时前
从零实现富文本编辑器#11-Immutable状态维护与增量渲染
前端·架构·前端框架
不想秃头的程序员3 小时前
Vue3 封装 Axios 实战:从基础到生产级,新手也能秒上手
前端·javascript·面试
数研小生4 小时前
亚马逊商品列表API详解
前端·数据库·python·pandas
你听得到114 小时前
我彻底搞懂了 SSE,原来流式响应效果还能这么玩的?(附 JS/Dart 双端实战)
前端·面试·github
不倒翁玩偶4 小时前
npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
前端·npm·node.js