例如,我有一个构建 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();
似乎没有太大区别,我有点困惑.
最佳答案
简短的回答
有no big difference在使用 new
运算符和在返回对象时删除它之间。
引用 "JavaScript Garden" :
If the function that was called has no explicit return statement, then it implicitly returns the value of this - the new object. In case of an explicit return statement, the function returns the value specified by that statement, but only if the return value is an Object.
语言规范告诉我们:
If Type(result) is Object then return result.
Return obj.
在[[construct]]
指定构造函数如何完成的算法。
语言规范简介
然而,对于你雄心勃勃的类型——让我们一起探讨为什么在语言规范中!我们怎么能自己解决这个问题?
这就是为什么,我们正在评估 new NewExpression
,其中 newExpression 是您的函数。我通过检查 new 关键字在索引中的作用到达那里。
首先:
- Let ref be the result of evaluating NewExpression.
这是函数调用
然后:
- Let constructor be GetValue(ref).
GetValue
里面的内容是:
Return the result of calling the GetBindingValue (see 10.2.1) concrete method of base passing GetReferencedName(V) and IsStrictReference(V) as arguments.
这将返回函数本身(基于 this )
If Type(constructor) is not Object, throw a TypeError exception.
函数是 JS 中的对象,所以这一切都很好。
If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
这会检查它是否是一个函数。所有函数都有一个构造方法(将函数视为构造函数,您可以尝试评估 (function(){}).constructor
并查看。
Return the result of calling the [[Construct]] internal method on constructor, providing no arguments (that is, an empty list of arguments).
太棒了!让我们看看 [[construct]]
做了什么。它在 13.3.2 中定义,它说了一堆东西。大奖是这样的:
Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
If Type(result) is Object then return result. Return obj.
叮叮叮!
所以在内部,规范说如果你的函数返回一个对象,构造函数返回它而不是创建的对象。
注意(一个非常小的区别是,当您不处于严格模式时,使用 new
可能会 catch a bug )
奖金:Here is a nice explanation on constructors from JavaScript garden
关于javascript - 什么时候应该在 JavaScript 中使用构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17225015/