为什么 JavaScript 中新对象的原型属性是 undefined?

阅读时长 4 分钟读完

JavaScript 是一门基于原型继承的语言,它使用原型链来实现继承。每个 JavaScript 对象都有一个 [[Prototype]] 内部属性,指向其原型对象。在访问对象属性时,如果该对象不存在该属性,则会沿着原型链向上查找,直到找到该属性或者到达原型链的顶端。

但是,在创建新的对象时,很多开发者会发现新对象的 prototype 属性是 undefined,而不是指向其构造函数的 prototype 属性。这似乎与整个原型继承机制相矛盾,引起了人们的困惑和疑问。

为什么会出现这种情况?

这个问题的根源在于 JavaScript 中的构造函数。在 JavaScript 中,构造函数也是一种函数,可以通过 new 运算符来创建新的对象实例。当我们创建一个新的对象时,实际上是通过调用构造函数来创建的,并且新对象的 [[Prototype]] 属性指向构造函数的 prototype 属性。

例如:

在这个例子中,我们创建了一个名为 Person 的构造函数,并通过 new 运算符创建了一个名为 person1 的新对象实例。由于 Person.prototype 是一个对象,因此新对象的 [[Prototype]] 属性指向 Person.prototype

然而,如果我们尝试直接访问构造函数的 prototype 属性,会发现它并不是对象类型,而是一个空对象:

这是因为在 JavaScript 中,每个函数都有一个 prototype 属性,但只有当该函数被作为构造函数使用时,才会将其 prototype 属性赋值给新对象的 [[Prototype]] 属性。

因此,新对象的 prototype 属性是 undefined,是因为它没有被赋值为构造函数的 prototype 属性。

如何解决这个问题?

虽然新对象的 prototype 属性是 undefined,但它仍然可以通过原型链访问到构造函数的 prototype 属性中定义的方法和属性。因此,在大多数情况下,这个问题并不会对实际开发造成太大的影响。

但是,如果你需要在新对象上动态添加新的方法或属性,并希望它们能够在原型链中被访问到,那么你可以使用 Object.create() 来创建一个新的对象,并将其原型设置为构造函数的 prototype 属性。

例如:

在这个例子中,我们使用 Object.create() 方法创建了一个新对象 person2,它的原型被设置为 Person.prototype。然后,我们可以将 name 属性设置为 'Bob'。由于新对象的原型指向 Person.prototype,因此我们可以访问到 Person.prototype 中定义的属性和方法。

总结

JavaScript 中新对象的 prototype 属性是 undefined,是因为它没有被赋值为构造函数的 prototype 属性。虽然这个问题可能会引起困惑,但在大多数情况下不会对实际开发造成太大影响。如果你需要在新对象上动态添加新的方法或属性,并希望它们能够在原型链中被访问到

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/25589

纠错
反馈