【发布时间】:2019-07-15 17:55:24
【问题描述】:
作为一个面向对象的 JavaScript 新手,我注意到没有过多强调语言“原型”和“构造函数”的歧义所造成的混乱,这让我怀疑我是否走在正确的轨道上或误解了整个概念。
例如here指的是下面的函数树:
function Tree(name) {
this.name = name;
}
当还有一个称为原型的属性时作为原型,如在 Object.prototype 中。前者是函数的类型,而后者是对象的属性。这有时会产生误导,因为当有人说对象的实例继承其原型的特性时,他们实际上是在说实例从称为原型的对象/函数类型继承称为原型的属性(更不用说原型之外还有其他属性)像 Object.is() 或 Object.keys() 这样没有继承的属性!)。
其次,构造器这个词经常被松散地使用,至少在初学者眼中是这样。例如,当人们说构造函数的原型时,他们是指person1 的函数Person(),其中person1 是Person() 的实例吗?或者他们的意思是person1.constructor?当说“构造函数的原型”时,是指 Object.constructor.prototype 还是构造函数 Person() 的原型?
进一步加剧混淆的是,有时 person1.constructor 实际上等同于构造函数 Person() 而实际上它们是两个不同的东西。 person1.constructor 的构造函数是 person1 对象的属性,而函数 Person() 是一种称为构造函数的函数。如果他们将名为构造函数的函数类型重命名为蓝图,那么很容易看出我所说的混淆是什么意思。
【问题讨论】:
-
好吧,“原型”和“构造函数”是相关的概念,但它们指的是完全不同的东西。 “构造函数”始终是一个函数,而“原型”可以是一个函数,但几乎总是只是一个常规对象。
-
就像我说的,MDN 页面是错误的。
Tree()不是原型,它是构造函数。我已经修复了页面。 “constructor”属性是对用于实例化对象的构造函数的引用。 -
@Kevvv 它是一个构造函数,是类实例的“构造函数”,因此将指向它的属性称为
.constructor是明智的。还能是什么?我没有看到任何歧义。 -
@Bergi 所以当我说树的构造函数是什么时,它是否应该总是表示 tree.constructor 和 Tree 因为它们指向同一个东西并且行为相同?
-
@Kevvv 是的,
Tree函数是tree的构造函数——它是使用new Tree构造的。它也可以通过tree.constructor访问。鉴于它们是同一个东西,“树的构造函数”这个词没有歧义:-)当然,在边缘情况下,它们指的是不同的东西,然后 - 但只有那时 - 它是重要的是要准确区分“tree对象的.constructor属性”和“用于构造tree对象的函数”。
标签: javascript oop constructor prototype