2016-02-29 42 views
5

我想了解JavaScript的(或至少是V8的)有关构造函数的行为。为什么构造函数返回对象,但不是JavaScript中的基元?

我知道,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进行了缩减,但这并不具有启发性。

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

+2

对于其中一个,它不是“错误和丑陋”,因为它没有按照你的想法去做。当它不是一个原始对象时为什么会返回一个基元? –

+3

简而言之:如果从构造函数返回一个基元,它将被忽略。如果您返回一个对象,则将其用作结果对象。这是否回答了这个问题?或者你在寻找这种行为的基本原理吗? – deceze

+5

它的行为方式是“因为规格说明是这样”。然而,我认为你所寻找的“为什么”的解释可能真的是基于意见的 - 你需要得到一个显示语言设计团队推理的答案,其他的只是某人的意见 - 例如,这里是我的:你已经调用'new',所以你期待一个对象,也许语言设计团队认为你应该总是得到一个对象,即使该函数返回一个原语,但我没有什么可靠的支持该推理。 –

回答

4

这是因为按照定义,构造的目的是生产的对象,而不是原语:

4.3.4 constructor

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

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

13.2.2 [[Construct]]

  • 结果是调用的结果[[调用]的˚F内部属性,提供OBJ值并且提供 传递到[[Construct]]的参数列表,作为参数
  • 如果Type结果)是Object,则返回结果
  • 返回obj
  • 事实上,这是一种invariant

    [[构建]]()

    • 返回值的类型必须是对象。
    +0

    像你评论中的链接。我没有发现。谢谢。我认为这没什么意义 - 但这不是意见的地方:)。 – BairDev

    相关问题