什么时候应该在JavaScript中使用构造函数?

Che*_*hev 3 javascript oop constructor function object

例如,我有这个构建Car对象的函数.

function Car() {
    var honkCount = 0;
    var honkHorn = function () {
        honkCount++;
        $results.html('HONK!<br />');
    };
    return {
        get honkCount() {
            return honkCount;
        },
        honk: honkHorn
    }
}
Run Code Online (Sandbox Code Playgroud)

两者似乎var car = new Car();var car = Car();没有太大的区别,我有点困惑自己.

Ben*_*aum 8

简短的回答

没有什么大的区别使用与new运营商和删除它,当你返回一个对象.

引用"JavaScript Garden":

如果被调用的函数没有显式的return语句,那么它会隐式返回this的值 - 新对象.在显式返回语句的情况下,该函数返回该语句指定的值,但仅当返回值是Object时.

语言规范告诉我们:

如果Type(result)是Object,则返回结果.

返回obj.

[[construct]]指定构造函数如何完成的算法中.


简短介绍一下语言规范

然而,对于你雄心勃勃的类型 - 让我们一起探讨语言规范中的原因!我们怎么能自己解决这个问题呢?

这就是为什么我们正在评估new NewExpressionnewExpression的功能.我通过检查新关键字在索引中的作用来到达那里.

第一:

  1. 设ref是评估NewExpression的结果.

这是函数调用

然后:

  1. 让构造函数为GetValue(ref).

里面GetValue去的是:

返回调用GetBindingValue(参见10.2.1)的结果,将getReferencedName(V)和IsStrictReference(V)作为参数传递给base.

这将返回函数本身(基于)

如果Type(构造函数)不是Object,则抛出TypeError异常.

函数是JS中的对象,所以它们都很好.

如果构造函数没有实现[[Construct]]内部方法,则抛出TypeError异常.

这检查它是否是一个功能.所有函数都有一个构造方法(将函数看作构造函数,您可以尝试评估(function(){}).constructor和查看.

返回在构造函数上调用[[Construct]]内部方法的结果,不提供任何参数(即,一个空的参数列表).

大!让我们看看是[[construct]]做什么的.它在13.3.2中定义,它说了很多东西.累积奖金是这样的:

设result是调用F的[[Call]]内部属性的结果,将obj作为this值提供,并将传递给[[Construct]]的参数列表作为args.

如果Type(result)是Object,则返回结果.返回obj.

丁丁丁!

所以在内部,规范说如果你的函数返回一个对象,构造函数会返回它而不是创建的对象.

注意(一个非常小的区别是当你没有处于严格模式时,使用new可能会捕到一个bug)


Bonus:这是一个很好的解释来自JavaScript garden的构造函数