【发布时间】:2020-12-05 10:21:59
【问题描述】:
在下面的代码中
function Hello(){
//
}
console.dir(Hello);
我的问题是:
Object从哪里以及如何进入Hello的原型对象?
将Object带到那里的幕后发生了什么?
【问题讨论】:
标签: javascript prototype prototype-programming
在下面的代码中
function Hello(){
//
}
console.dir(Hello);
我的问题是:
Object从哪里以及如何进入Hello的原型对象?
将Object带到那里的幕后发生了什么?
【问题讨论】:
标签: javascript prototype prototype-programming
不要将prototype 作为函数的属性与其实际原型混淆(可通过__proto__/getPrototypeOf() 访问并用于名称解析机制等)。
在您的示例中,Hello.prototype 用作使用构造函数模式创建的所有对象的共享原型:也就是说,当使用 new 运算符调用此函数时。是的,这个原型本质上是一个对象:
function Hello() {}
console.log(Hello.prototype); // {}
console.log(Object.getPrototypeOf(Hello)); // function () { [native code] }
const newHello = new Hello();
console.log(Object.getPrototypeOf(newHello) === Hello.prototype); // true
const anotherHello = new Hello();
console.log(Object.getPrototypeOf(anotherHello) === Hello.prototype); // true
console.log(Object.getPrototypeOf(newHello) === Object.getPrototypeOf(anotherHello));
// apparently true as well
这就是 JS 中基于原型的对象模型的关键思想:实例之间共享的所有东西都只存储一次。
请注意,箭头函数没有prototype 属性(因为您不希望将它们用作构造函数):
const FatArrowHello = () => {};
console.log(FatArrowHello.prototype); // undefined
const newFatArrowHello = new FatArrowHello();
// VM424: 1 Uncaught TypeError: FatArrowHello is not a constructor
// at < anonymous >: 1: 18
【讨论】:
Hello 的原型对象中 Object 是从哪里来的,又是怎么来的?
它没有,但控制台显示确实使它看起来像那样。 Hello.prototype上的对象原型其实是Object.prototype,而不是Object:
function Hello() {
}
console.dir(Hello);
console.log(Hello.prototype.__proto__ === Object); // false
console.log(Hello.prototype.__proto__ === Object.prototype); // true
控制台将Object 显示为Hello.prototype.__proto__ 的类型(粗略地说),而不是其值。
(注意:我在上面使用了__proto__,因为这就是控制台在您的示例中向您显示它的方式,但我强烈建议不要使用__proto__ 访问器代码。请改用Object.getPrototypeOf。)
我想你知道这一点,但为了完整性:Hello.prototype 的原型是 Object.prototype 的原因是传统函数(和 class 构造函数)的 prototype 属性是由 JavaScript 引擎创建的当它创建函数时。对于传统的函数和基类,原型对象的创建就像使用对象字面量:{}。所以那个对象有Object.prototype 作为它的原型。 (使用extends 的类的工作方式略有不同。)
【讨论】: