Javascript 构造函数属性的意义是什么?

2022-08-30 05:07:30

试图绕着Javascript对OO的看法弯曲...而且,像许多其他人一样,对财产感到困惑。特别是,该属性的重要性,因为我似乎无法使其产生任何影响。例如:constructorconstructor

function Foo(age) {
    this.age = age;
}

function Bar() {
    Foo.call(this, 42);
    this.name = "baz"; 
}

Bar.prototype = Object.create(Foo.prototype); 
var b = new Bar;    

alert(b.constructor); // "Foo". That's OK because we inherit `Foo`'s prototype.
alert(b.name);        // "baz". Shows that Bar() was called as constructor.
alert(b.age);         // "42", inherited from `Foo`.

在上面的示例中,对象似乎具有名为 () 的正确构造函数 – 并且它从 继承了 age 属性。那么,为什么很多人建议这是必要的步骤:bBarFoo

Bar.prototype.constructor = Bar;

显然,在构造时调用正确的构造函数,那么这个原型属性有什么影响呢?我很好奇,“正确”设置构造函数属性实际上有什么实际区别 - 因为我看不到它对创建对象后实际调用哪个构造函数有任何影响。Barb


答案 1

第一步是了解什么是和全部。这并不难,但人们必须放弃古典意义上的“继承”。constructorprototype

构造函数

该属性不会在程序中产生任何特定效果,只是您可以查看它以查看哪个函数与运算符结合使用以创建对象。如果您键入它将是,并且您键入它将是.constructornewnew Bar()Barnew FooFoo

原型

该属性用于查找,以防相关对象没有要求的属性。如果你写,JavaScript 会尝试在 的属性中查找。如果找不到它,它将在 .如果它也不在那里,只要定义,它就会查看,依此类推。prototypex.attrattrxx.__proto__x.__proto__.__proto____proto__

那么它与什么以及它有什么关系?简而言之,是用于“类型”,而是用于“实例”。(我用引号说,因为类型和实例之间没有任何区别)。当你写的时候,发生的事情(除其他事项外)是设置为 。__proto__prototypeprototype__proto__x = new MyType()x.__proto___MyType.prototype

问题

现在,以上应该是你推导出你自己的例子意味着什么所需要的一切,但要尝试回答你的实际问题;“为什么要写这样的东西”:

Bar.prototype.constructor = Bar;

我个人从未见过它,我发现它有点傻,但是在你给出的上下文中,它将意味着-object(通过使用创建)将伪装成由而不是.我想这个想法是一些类似于C++ / Java / C #类语言的东西,其中类型查找(属性)将始终产生最具体的类型,而不是原型链中更通用的对象的类型。Bar.prototypenew Foo(42)BarFooconstructor

我的建议是:不要过多地考虑JavaScript中的“继承”。接口和 mixin 的概念更有意义。并且不要检查对象的类型。检查所需的属性(“如果它像鸭子一样走路,像鸭子一样嘎嘎叫,它就是鸭子”)。

试图将JavaScript强制到一个经典的继承模型中,而它所拥有的只是如上所述的原型机制,这就是导致混乱的原因。许多建议手动设置 -属性的人可能试图这样做。抽象很好,但是这种构造函数属性的手动赋值并不是JavaScript的惯用用法。constructor


答案 2

2020 年 9 月更新

下面的答案来自 ECMAScript 3 的时代,第一句话不再正确,因为自 ECMAScript 6 以来,该属性在少数地方使用。但是,我认为整体要点仍然适用。感谢T. J. Crowder在评论中指出这一点,请阅读他的答案,以更全面地了解当前情况。constructor

原始答案

该物业对内部的任何事情都没有实际影响。仅当代码显式使用它时,它才有任何用处。例如,您可能决定需要每个对象都具有对创建它的实际构造函数的引用;如果是这样,则需要在设置继承时通过将对象分配给构造函数的属性来显式设置属性,如示例所示。constructorconstructorprototype