【问题标题】:Why do constructor functions return objects, but not primitives in JavaScript? [duplicate]为什么构造函数返回对象,而不是 JavaScript 中的基元? [复制]
【发布时间】:2016-02-29 15:09:23
【问题描述】:

我正在尝试了解 JavaScript(或至少 V8 的)关于构造函数的行为。

我知道,JavaScript 构造函数永远不应该返回任何东西(所以:undefined)。

但是考虑一下这个 JavaScript:

function Thing() { 
  return '';
}
var t = new Thing();
console.log(t, typeof t); // => Thing {} "object"

现在,如果你这样做:

function Thing() { 
  return { hi: '' };
}
var t = new Thing();
console.log(t, typeof t); // => Object {hi: ""} "object"

甚至:

function Thing() { 
  this.a = 'a';
  return { hi: '' };
}
var t = new Thing();
console.log(t, typeof t); // => Object {hi: ""} "object"

那么,如果你写这种代码,为什么 JavaScript 中的构造函数返回一个对象,而不是一个原始类型?


this SO answer 中也提到了这种行为,但没有解释。我还浏览了 ECMAScript 规范的 The new Operator 部分,它的 Construct 被剪掉了,但这并不具有启发性。

任何提示或知识(请用简单的英语)?

【问题讨论】:

  • 好吧,这不是“错误和丑陋”,因为它没有按照您的想法行事。为什么它不是原始对象时会返回原始对象?
  • 简而言之:如果你从构造函数返回一个原语,它会被忽略。如果您返回一个对象,它将用作结果对象。这能回答问题吗?或者您是否正在寻找这种行为的理由?
  • 它的行为方式是“因为规范是这样说的”。但是,我认为您正在寻找的“为什么”解释可能确实基于意见 - 您需要得到一个显示语言设计团队推理的答案,其他任何内容都只是某人的意见 - 例如,这是我的:你已经调用了new,所以你期待一个对象,也许语言设计团队认为你应该总是得到一个对象,即使函数返回一个原语,但我没有任何可靠的理由支持这个推理。
  • 继续@James 的推理……函数可能会返回类似true 或false 的副作用,可以放心地忽略它;但是如果返回一个“严重”的对象,那可能应该是 object 构造函数的返回值。
  • @malte new operator 调用 [[Construct]],它执行此操作。

标签: javascript constructor


【解决方案1】:

这是因为,根据定义,构造函数的目的是生成对象,而不是原语:

4.3.4 constructor

创建和初始化对象的函数对象

因此,[[Construct]] 内部方法(通过new operator 调用)检查[[Call]] 返回的值的类型:

13.2.2 [[Construct]]

  1. 令result为调用F的[[Call]]内部属性的结果,提供obj作为this 重视和提供 作为 args 传递给 [[Construct]] 的参数列表。
  2. 如果Type(result) 是对象,则返回result。
  3. 返回obj。

其实这是invariant:

[[构造]] ( )

  • 返回值的类型必须是 Object。

【讨论】:

  • 喜欢您评论中的链接。我没有发现。谢谢。在我看来这没有多大意义——但这不是发表意见的地方:)。
猜你喜欢
  • 2019-11-07
  • 2020-02-29
  • 2014-05-04
  • 1970-01-01
  • 2018-01-29
  • 2015-06-10
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多