在许多编程语言中,我需要将某些函数直接调用新实例封装到括号中:
(new Date()).toString()
在JS中,new Date().toString()
和Date().toString()
的结果是相同的。
是否可以在实例化新对象后立即使用函数调用的方式?
看起来new
关键字有时是可选的。这在JS引擎中如何解释?
在许多编程语言中,我需要将某些函数直接调用新实例封装到括号中:
(new Date()).toString()
在JS中,new Date().toString()
和Date().toString()
的结果是相同的。
是否可以在实例化新对象后立即使用函数调用的方式?
看起来new
关键字有时是可选的。这在JS引擎中如何解释?
new Date;
而不带括号,这个操作符new(没有参数列表)
的优先级低于函数调用。因此,new Date.toString()
被解释为new(Date.toString)()
,您会收到一个错误,指出toString()
不是构造函数。
看起来有时候new关键字是可选的。JS引擎如何解释这个?
完全不是这样。这不是JS的特性,而是这些函数/类/构造函数实现中的怪癖。
有点像这些实现:
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构造函数具有(由规范定义)两个不同的返回值,具体取决于您将其作为函数调用还是作为构造函数调用。new Date().toString()
=(new Date()).toString()
和 new Date.toString()
=new (Date.toString)()
。 - ANTARA2+3*4
被解释为 2+(3*4)
而不是 (2+3)*4
。这就是所谓的运算符优先级。 - ThomasDate构造函数是%Date%内置对象,也是全局对象Date属性的初始值。当作为构造函数调用时,它会创建并初始化一个新的Date对象。当以函数形式而非构造函数形式调用Date时,它会返回一个表示当前时间(协调世界时)的字符串。
// 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
最后,您可以立即使用新创建的对象,无需将其包装在括号中。
new Date().toString()
和Date().toString()
的结果是相同的。但是,new Date()
是一个日期对象,而Date()
是一个字符串。这两者的toString()方法返回相同的结果只是“巧合”。 - Freeman Lambda