🎯 面试标准回答(推荐结构)
1️⃣ 概念定义(30秒)
"原型是 JavaScript 实现继承的机制。每个 JavaScript 对象都有一个内部属性
[[Prototype]](可通过__proto__访问),它指向该对象的原型对象。当我们访问对象的属性或方法时,如果对象本身没有,JavaScript 会沿着原型链向上查找,直到找到该属性或到达原型链的顶端null。"
2️⃣ 举例说明(1分钟)
let obj = { age: 25 }
// obj 可以使用很多方法,比如:
obj.toString()
obj.hasOwnProperty('age')
// 这些方法并不是 obj 自己定义的
// 而是通过 __proto__ 从原型对象上继承来的
console.log(obj.__proto__ === Object.prototype) // true
3️⃣ 核心关系(1分钟)
面试官可能追问,这时你可以说明三个关键关系:
function Person(name) {
this.name = name
}
let person = new Person('张三')
// 三角关系:
// 1. 实例的 __proto__ 指向构造函数的 prototype
person.__proto__ === Person.prototype // true
// 2. 原型的 constructor 指向构造函数
Person.prototype.constructor === Person // true
// 3. 构造函数的 prototype 是一个对象
typeof Person.prototype === 'object' // true
4️⃣ 原型链(30秒-1分钟)
// 原型链:对象通过 __proto__ 连接起来的链条
person.__proto__ === Person.prototype
Person.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null // 原型链的终点
"当访问 person.toString() 时,查找过程是:
- 先看 person 对象自身有没有
- 没有就去 Person.prototype 找
- 还没有就去 Object.prototype 找
- 再没有就返回 undefined"
5️⃣ 加分项(如果时间允许)
可以补充的高级知识点:
-
性能优化
// 方法定义在原型上,所有实例共享,节省内存 Person.prototype.sayHello = function() { console.log('Hello, ' + this.name) } -
原型污染风险
// 修改原型会影响所有实例 Object.prototype.hack = 'danger' console.log({}.hack) // 'danger' - 所有对象都被污染 -
现代替代方案
// ES6 后推荐使用 Object.getPrototypeOf() 和 Object.setPrototypeOf() // 而不是直接操作 __proto__ Object.getPrototypeOf(obj) === Object.prototype
📝 面试回答模板(完整版)
【第1层 - 基础定义】
"原型是 JavaScript 的继承机制。每个对象都有一个内部属性指向它的原型,
我们可以通过 __proto__ 访问。原型本身也是一个对象。"
【第2层 - 作用说明】
"原型的作用是实现属性和方法的共享。比如我创建一个对象 let obj = {},
虽然我没有定义 toString 方法,但 obj 可以调用 obj.toString(),
这是因为它从 Object.prototype 上继承了这个方法。"
【第3层 - 原型链】
"多个对象通过 __proto__ 连接起来就形成了原型链。JavaScript 查找属性时,
会沿着原型链向上查找,直到找到该属性或到达 null 为止。"
【第4层 - 构造函数关系】
"对于构造函数来说,有三个关键关系:
1. 实例的 __proto__ 指向构造函数的 prototype
2. 构造函数的 prototype.constructor 指回构造函数本身
3. 所有函数的 __proto__ 最终指向 Function.prototype"
【第5层 - 实际应用】
"在实际开发中,我们通常把共享的方法定义在原型上,这样所有实例都能访问,
同时节省内存。ES6 的 class 语法本质上也是基于原型的语法糖。"
🔥 常见追问及回答
Q1: "原型和原型链的区别?"
A: "原型是单个对象,原型链是多个原型对象通过 __proto__ 连接形成的链条。原型解决的是属性共享,原型链解决的是属性查找。"
Q2: "__proto__ 和 prototype 有什么区别?"
A:
__proto__是每个对象都有的属性,指向它的原型prototype是函数才有的属性,指向通过该函数创建的实例的原型- 实例的
__proto__=== 构造函数的prototype
Q3: "如何判断属性是对象自己的还是原型上的?"
A:
obj.hasOwnProperty('age') // 判断是否是自有属性
'age' in obj // 判断对象及其原型链上是否有该属性
Q4: "原型链的顶端是什么?"
A: "Object.prototype.__proto__ 是 null,这是原型链的终点。"
💡 面试技巧
- 先答概念,再举例子:不要一上来就讲细节
- 画图辅助:如果是白板面试,画出原型链关系图会大加分
- 联系实际:提到 ES6 class、继承、性能优化等实际应用
- 层次清晰:从简单到复杂,根据面试官反应调整深度
- 准备代码:最好能手写一个原型链的例子
记住:面试不是背书,而是展示你的理解深度。