例如,我有这个函数来构建一个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();
似乎没有太大区别,我有点困惑自己。
答案 0 :(得分:8)
使用new
运算符并在返回对象时删除它之间有no big difference。
如果被调用的函数没有显式的return语句,那么它会隐式返回this的值 - 新对象。如果是显式返回语句,则该函数返回该语句指定的值,但仅当返回值为Object时才会返回。
语言规范告诉我们:
如果Type(result)是Object,则返回结果。
返回obj。
在[[construct]]
算法中指定构造函数的完成方式。
但是,对于雄心勃勃的类型 - 让我们一起探讨语言规范中的原因!我们怎么能自己想出来呢?
这就是为什么我们要评估new NewExpression
newExpression是你的功能。我通过检查新关键字在索引中的作用来实现目标。
第一:
- 让ref成为评估NewExpression的结果。
醇>
这是函数调用
然后:
- 让构造函数为GetValue(ref)。
醇>
GetValue
内的内容:
返回调用GetBindingValue(参见10.2.1)的结果,该方法将GetReferencedName(V)和IsStrictReference(V)作为参数传递。
这将返回函数本身(基于this)
如果Type(构造函数)不是Object,则抛出TypeError异常。
函数是JS中的对象,所以它都很好。
如果构造函数没有实现[[Construct]]内部方法,则抛出TypeError异常。
这检查它是否是一个功能。所有函数都有一个构造方法(将函数看作构造函数,您可以尝试评估(function(){}).constructor
并查看。
返回在构造函数上调用[[Construct]]内部方法的结果,不提供任何参数(即,一个空的参数列表)。
大!让我们看看[[construct]]
的作用。它在13.3.2中定义,它说了很多东西。累积奖金是这样的:
<丁>丁丁!让结果成为调用F的[[Call]]内部属性的结果,将obj作为此值提供,并将传递给[[Construct]]的参数列表作为args。
如果Type(result)是Object,则返回结果。 返回obj。
在内部,规范说如果你的函数返回一个对象,构造函数会返回它而不是创建的对象。
注意(一个非常小的区别是当你没有处于严格模式时,使用new
可能catch a bug)
奖金:Here is a nice explanation on constructors from JavaScript garden
答案 1 :(得分:4)
var car = new Car();
和var car = Car();
似乎没有太大区别,我有点困惑自己。
你是对的,它们都是一样的,只是因为你从函数中返回一个对象。 From the MDN documentation:
3。构造函数返回的对象将成为整个新表达式的结果。如果构造函数未显式返回对象,则使用在步骤1中创建的对象。 (通常构造函数不返回值,但如果他们想要覆盖正常的对象创建过程,他们可以选择这样做。)
正如文档中所说,通常构造函数不会显式返回值。
答案 2 :(得分:0)
有人在javascript中复制了一个关于Closure的简单例子。使用new函数的原因是创建一个闭包,但这是一个无用的例子。这是使用Closure的更好方法。请注意,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的新的和javascript闭包。