js原型与原型链认识面试题
时间: 2025-04-12 09:33:12 浏览: 26
<think>嗯,用户问的是关于JavaScript原型和原型链的面试题,我需要详细介绍一下这个知识点。首先,我应该从基本概念开始,解释什么是原型和原型链,然后逐步深入,可能还要举一些例子来帮助理解。
首先,原型是什么?每个JavaScript对象都有一个原型对象,对象会继承原型的属性和方法。构造函数通过prototype属性指向原型,而实例对象通过__proto__属性访问原型。这一点可能需要详细说明,比如构造函数、实例、原型之间的关系。
然后原型链是什么?当访问一个对象的属性时,如果对象自身没有,就会去原型上找,原型又有自己的原型,这样一层层往上,直到找到或者到达null,形成链条。这个过程就是原型链。这里可能需要画个示意图或者用代码示例来说明。
接下来,常见的面试题可能涉及如何实现继承,instanceof的原理,或者如何判断属性是对象自身还是继承来的。比如,hasOwnProperty方法的作用,或者手写一个instanceof函数。这些都需要准备例子和解释。
还有可能问到ES6的class语法和原型继承的关系,毕竟class只是语法糖,底层还是基于原型链的。这部分需要对比传统原型继承和class的区别,说明其原理。
另外,可能会涉及一些陷阱题,比如修改原型的影响,或者原型链污染的问题。例如,给Array原型添加方法会影响所有数组实例,这可能引发的问题需要注意。
在回答结构上,应该分点清晰,先讲原型,再讲原型链,然后举例说明,接着讨论相关方法和应用,最后总结常见考点。同时,要确保术语准确,比如__proto__和prototype的区别,constructor属性的指向等。
需要检查自己是否遗漏了重要概念,比如Object.create的作用,或者new操作符的内部步骤。这些都可能出现在面试题中。比如,new一个构造函数时,发生了什么,如创建空对象、绑定原型、执行构造函数、返回对象等步骤。
可能还需要解释为什么函数也是对象,因为函数有prototype属性,而函数本身又是Function的实例,这涉及到Function和Object的关系,这部分比较绕,需要用简单明了的例子说明。
最后,确保语言通俗易懂,避免过于晦涩,同时保持专业性。可能需要用代码片段来辅助解释,比如构造函数、实例、原型之间的关系,以及原型链的查找过程。</think>### JavaScript 原型与原型链核心知识点(面试题解析)
---
#### 一、基础概念
1. **原型(Prototype)**
- 每个 JavaScript **对象**都有一个隐藏属性 `[[Prototype]]`(通过 `__proto__` 访问),指向它的原型对象。
- **构造函数**通过 `prototype` 属性指向其原型对象,例如:
```javascript
function Person() {}
console.log(Person.prototype); // 原型对象
```
$$ \text{构造函数} \xrightarrow{\text{prototype}} \text{原型对象} $$
2. **原型链(Prototype Chain)**
- 对象查找属性时,若自身不存在,会通过 `__proto__` 逐级向上查找原型链,直到 `Object.prototype.__proto__`(即 `null`):
$$ \text{实例} \xrightarrow{\text{__proto__}} \text{构造函数原型} \xrightarrow{\text{__proto__}} \text{Object.prototype} \xrightarrow{\text{__proto__}} \text{null} $$
---
#### 二、高频面试题解析
**1. 如何实现继承?**
```javascript
// 父类
function Animal(name) {
this.name = name;
}
Animal.prototype.say = function() { console.log(this.name); };
// 子类继承
function Dog(name) {
Animal.call(this, name); // 继承属性
}
Dog.prototype = Object.create(Animal.prototype); // 继承方法
Dog.prototype.constructor = Dog; // 修复构造函数指向
```
**2. `instanceof` 的原理是什么?**
- 检查右侧构造函数的 `prototype` 是否在左侧对象的原型链上:
```javascript
function myInstanceof(obj, Constructor) {
let proto = obj.__proto__;
while (proto) {
if (proto === Constructor.prototype) return true;
proto = proto.__proto__;
}
return false;
}
```
**3. `Object.create(null)` 和 `{}` 的区别?**
- `Object.create(null)` 创建的对象无原型链(`__proto__` 为 `undefined`),适合纯粹的数据存储。
---
#### 三、关键方法
1. **`hasOwnProperty`**
判断属性是否为对象自身所有(非继承):
```javascript
const obj = { a: 1 };
obj.hasOwnProperty('a'); // true
```
2. **`Object.getPrototypeOf(obj)`**
标准方法获取对象的原型(替代 `obj.__proto__`)。
---
#### 四、常见陷阱题
**题目:以下代码输出什么?**
```javascript
function Foo() {}
const f1 = new Foo();
console.log(f1.constructor === Foo); // true
console.log(f1.constructor === Object); // false
```
**解析**:
- `f1` 自身无 `constructor`,通过原型链找到 `Foo.prototype.constructor`(指向 `Foo`)。
- 若修改 `Foo.prototype = {}`,则 `f1.constructor` 会指向 `Object`。
---
#### 五、总结高频考点
1. 原型链的查找机制
2. 继承的多种实现方式(组合继承、寄生组合继承)
3. `new` 操作符的底层步骤(创建对象、绑定原型、初始化属性)
4. ES6 `class` 与原型的关系(语法糖本质)
理解这些核心概念后,可结合手写代码(如实现 `new`、继承)巩固知识。
阅读全文
相关推荐
















