返回

函数的 __proto__ 属性:为何指向原型对象而非自有原型?

javascript

函数的 __proto__ 属性:一个隐秘的谜团

导言

在 JavaScript 中,__proto__ 属性是一个谜团。它似乎指向对象的原型对象,但在函数上,它却不是自有属性,而是继承自 Function.prototype。那么,为什么 __proto__ 不在函数上?

原型链

要理解 __proto__ 的行为,我们必须了解 JavaScript 的原型链。原型链是一个对象及其原型对象的连接链。当一个对象访问一个不存在的属性时,它会沿着原型链向上查找,直到找到该属性或到达原型链的末尾(Object.prototype)。

函数也有自己的原型链,如下所示:

Function -> Function.prototype -> Object.prototype -> null

函数上的 __proto__

当我们使用 __proto__ 访问函数的属性时,它会沿着原型链向上查找,首先是 Function.prototype,然后是 Object.prototype,最后是 null。这意味着函数的 __proto__ 属性指向其原型对象,而不是它自己的原型对象。

示例

让我们看一个示例:

function Bar() {}

const a = new Bar();
const b = new Bar();

console.log(a.__proto__ === b.__proto__); // true

ab 都是 Bar 的实例,因此它们的原型对象都是 Bar.prototype。但是,a.__proto__b.__proto__ 都指向 Bar.prototype,而不是 Object.prototype

结论

__proto__ 属性在函数上不是自有属性,因为它用于访问函数的原型对象,而不是它自己的原型对象。对于函数来说,它们的原型链是 Function -> Function.prototype -> Object.prototype -> null。因此,函数的 __proto__ 属性指向其原型对象,而不是 Object.prototype

常见问题解答

1. 为什么函数的 __proto__ 属性不是自有属性?

因为 __proto__ 属性用于访问对象的原型对象,而不是它自己的原型对象。

2. 函数的原型链是什么?

Function -> Function.prototype -> Object.prototype -> null

3. 当一个函数访问一个不存在的属性时会发生什么?

它会沿着原型链向上查找,直到找到该属性或到达原型链的末尾。

4. a.__proto__b.__proto__ 指向什么?

它们都指向 Bar.prototype,而不是 Object.prototype

5. 如何更改函数的原型对象?

可以通过 Object.setPrototypeOf() 方法来更改函数的原型对象。