javascript 针对 C++ 程序员的新解释

javascript new explained for c++ programmers

背景

我正在努力创建一个函数,该函数从 JSON 获取以毫秒为单位的时间戳并将其转换为人类可读的格式。我尝试了 alert(Date(jsonData.timestamp).toISOString()),结果是“Date(...).toISOString 不是函数”。

但是在我查过的时间格式化示例中它起作用了,很快我注意到要使用的模式是 let myDate=new Date(...); alert(myDate.toISOString())。我尝试了 Invalid Date。所以出于某种原因 Date()new Date() 对参数的解释不同。

我想也许我从 JSON 获得的值是一个字符串,当我这样做时我应该将其作为数字传递,我最终得到两个不同的日期:

new Date(1594720804236643));    // result differs from thjsut calling Date, without new
new Date("1594720804236643")); //does not work

我认为 surly copy construciton 会起作用,结果是:

let myDate=Date(jsonData.timestamp);
let myDateObject=new Date(myDate);
alert(myDateObject.toISOString());

虽然我有一个(可怕的、丑陋的)解决方案,但我想了解 new

的细微差别

实际问题

MyClass()new MyClass()的区别在哪里,有C++编程背景的人认为区别只是对象是分配在栈上还是堆上。在 Javascript 中,显然规则不同。一方面参数的解释发生了变化,另一方面,结果对象上可用的函数集也不同。

这是一个构造函数的通用模式,出于其自身的设计原因,无论是否使用 new 调用它都希望以相同的方式运行:

function NewIsOptional() {
  if (this == null || !(this instanceof NewIsOptional))
    return new NewIsOptional();
  // normal constructor work
}

这个技巧通过检查 this 起作用。如果它没有被绑定(如果缺少 new 就会出现这种情况)或者如果它被绑定到错误的类型,代码将通过 new 进行递归调用。通过构造函数将看到 this 正确绑定到一个新对象,因此它将继续执行其正常操作。

现在,并非所有构造函数都这样做。我不确定我是否写过一个,而且我输入了很多代码。如果未通过 new 调用某些构造函数,则会抛出异常。一些,例如符号“构造函数”,如果它们 调用 new 则抛出异常。某些构造函数(如 Date 或 Boolean)在未使用 new.

调用时会做完全不同的事情

基本上没有什么规矩。构造函数是一个函数,构造函数中的代码可以为所欲为。它可以类型检查参数值并决定不同的行为或决定抛出错误。它可以调用其他函数,如果它是在一个函数中创建的,则可以操作它的闭包,当然还可以做一些普通的事情,比如初始化对象属性(这是最常见的事情)。

此外,请注意特定构造函数如何解释其参数,以及当它通过或不通过 new 调用时它的行为如何,是两个完全正交的事情。也没有规则。构造函数可以自由地完全相同地解释带有或不带有 new 的参数,或者它可以完全不同地解释它们。这些背后都没有基本的语言规则。