在许多语言中,要直接在新实例上调用某些函数,我需要将其包装成大括号:
(new Date()).toString()
在JS new Date().toString()
和Date().toString()
中也会给出相同的结果。
是否允许在以这种方式实例化新对象后立即使用函数调用?
看起来new
关键字有时是可选的。这怎么解释JS引擎?
答案 0 :(得分:3)
在许多语言中,要直接在新实例上调用某些函数,我需要将其包装到大括号中 是否允许在以这种方式实例化新对象后立即使用函数调用?
我认为这里的问题是潜在的模棱两可。虽然(new Date()).toString()
已明确,new Date().toString()
可能(理论上)表示(new Date()).toString()
或new (Date().toString)()
。
但operator precedence来救援。
new (with argument list)
运算符的优先级高于函数调用。因此,new Date().toString()
中的执行顺序与(至少是引擎)一样清晰,因为必须执行这些数学运算的顺序2 + 3 * 4
但请注意,在JS中,您也可以在不使用括号的情况下编写new Date;
,并且此运算符new (without argument list)
的优先级低于函数调用。因此,new Date.toString()
被解释为new (Date.toString)()
,并且您会收到toString()
不是构造函数的错误。
看起来新关键字有时是可选的。这是如何由JS引擎解释的?
完全没有。这不是JS特性,这是实现这些函数/ classes / constructors
的一个怪癖有点像这些实现:
function Foo(){
if(!(this instanceof Foo))
return new Foo();
this.foo = 42;
}
//or something like
function Bar(){
return Object.create(Bar.prototype, {
bar: { value: 42 }
});
}
console.log(new Foo(), Foo());
console.log(new Bar(), Bar());
再次提防。由于增加了安全性/故障安全性,您无法使用新的class
关键字实现类似的功能。它添加了(隐藏)代码,以确保始终使用new
关键字调用这些构造函数,否则构造函数会抛出错误。
修改强> 例如,Array构造函数的工作方式与上面描述的相似,但看起来如Freeman Lambdas answer中指出的那样),Date构造函数具有(由规范定义)两个不同的返回值,具体取决于是否为你把它称为函数或构造函数。
答案 1 :(得分:2)
Date构造函数是%Date%内在对象和初始对象 全局对象的Date属性的值。当被称为 构造函数,它创建并初始化一个新的Date对象。当日期是 作为函数而不是作为构造函数调用,它返回一个String 代表当前时间(UTC)。
// with new
const a = new Date();
console.log(typeof a); // object
console.log(a instanceof Date); // true
console.log(a.toString()); // date formatted string
// without new
const b = Date();
console.log(typeof b); // string
console.log(b instanceof Date); // false
console.log(b.toString()); // date formatted string
正如您所看到的,在语言规范中明确描述了Date的这种行为,它与 new 是可选的无关。 通过阅读这些热门问题,您可以发现很多关于 new 的信息:https://stackoverflow.com/search?q=javascript+new+keyword
最后,您可以立即使用新创建的对象。没有必要将它包装在括号中。