【面试常考】JS原型链

1.理解
(1)显式原型

每个函数在定义的时候都有一个显式原型prototype,默认指向一个空的Object对象。
function People() {
	//this.prototype = {}
}

(2)隐式原型

每个对象实例都有一个隐式原型__proto__,指向创建它的构造函数的显示原型。
let p = new People() //p.__proto__ = People.prototype

(3)显式原型与隐式原型的关系

被创建实例对象的隐式原型等于创建它的构造函数的显式原型。
p.__proto__ = People.prototype

2.应用

在这里插入图片描述
3.注意
(1)Object的显式原型是原型链的尽头。

Object.prototype.__proto__ === null

(2)所有函数都是Function对象的实例(包括Function自身)。

console.log(Function.__proto__ === Function.prototype)

(3)原型链是JS实现继承的一种方法。

<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`、继承)巩固知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值