3

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

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

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

4

3 回答 3

8

简短的回答

在返回对象时使用运算符和删除它没有太大区别。new

引用“JavaScript 花园”

如果被调用的函数没有显式的 return 语句,那么它会隐式返回 this 的值——新对象。在显式返回语句的情况下,函数返回该语句指定的值,但前提是返回值是一个对象。

语言规范告诉我们:

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

返回对象。

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


语言规范的简短介绍

但是,对于您雄心勃勃的类型 - 让我们一起在语言规范中探讨原因!我们怎么能自己想出来呢?

这就是为什么,我们正在评估new NewExpressionnewExpression 是您的函数的原因。我通过检查新关键字在索引中的作用到达那里。

第一的:

  1. 令 ref 为计算 NewExpression 的结果。

这是函数调用

然后:

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

里面GetValue去:

返回调用 GetBindingValue(参见 10.2.1)具体方法的结果,该方法将 GetReferencedName(V) 和 IsStrictReference(V) 作为参数传递。

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

如果 Type(constructor) 不是 Object,则抛出 TypeError 异常。

函数是 JS 中的对象,所以一切都很好。

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

这会检查它是否是一个函数。所有函数都有构造方法(把函数看成构造函数,你可以试试评估(function(){}).constructor看看。

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

伟大的!让我们看看有什么[[construct]]作用。它在13.3.2中定义中定义,它说了很多事情。大奖是这样的:

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

如果 Type(result) 是 Object 则返回结果。返回对象。

叮叮叮!

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

注意(一个很小的区别是,当您不在严格模式下时,使用new可能会遇到错误


奖励:这是对 JavaScript garden 中构造函数的一个很好的解释

于 2013-06-20T22:44:10.197 回答
4

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

你是对的,它们都是一样的,只是因为你从函数中返回了一个对象。从 MDN 文档

3.构造函数返回的对象成为整个new表达式的结果。如果构造函数没有显式返回对象,则使用在步骤 1 中创建的对象。(通常构造函数不返回值,但如果他们想覆盖正常的对象创建过程,他们可以选择这样做。)

正如文档中所说,通常构造函数不会显式返回值。

于 2013-06-20T22:44:41.177 回答
0

有人在javascript中复制了一个简单的闭包示例。将 new 与函数一起使用的原因是创建一个闭包,但这是一个无用的示例。这是使用闭包的更好方法。请注意,honkCount 仅适用于 honkHorn 和 get_honkCount 这两种方法:

function Car() {
    var honkCount = 0;
    this.honkHorn = function () {
        honkCount++;
        $results.html('HONK!<br />');
    };
    this.get_honkCount = function() {
            return honkCount;
    };
}

var car1 = new Car();
var car2 = new Car();
car1.honkHorn();
car1.honkHorn();
car2.honkHorn();

alert('car1 honks: ' + car1.get_honkCount());
alert('car2 honks: ' + car2.get_honkCount());

所以现在你看到这两个对象作为实例化的私有变量明显地跟踪喇叭,这要归功于 honkCount 的 new 和 javascript 闭包。

于 2013-06-20T23:28:39.710 回答