为什么在引用时Date返回一个日期而不是对象的引用?

时间:2018-07-18 07:24:44

标签: javascript date object types

没什么大问题,但是它属于wat,所以我很好奇。

如果您在JS中创建一个新的Date,然后引用它,则它将返回看起来像日期值的东西,而不是像其他对象一样描述其属性(IE:Date{date: "some date"})。它看起来像一个值,而不是一个对象,但它绝对是一个对象。 Chrome的检查器还可以通过指出文本的颜色变化以及由于文本不是字符串而缺少" "来指出这一点。

IE:

let date = new Date()
let person = {
  name: 'mike'
}

console.log(person) // {name:"mike"} or: Person {name:"mike"} <- obj description
console.log(person.name) // "mike" <- value

console.log(date) // Tue Jul 17 2018 22:53:29 GMT-0700 (Pacific Daylight Time) <- value?? 
// Why no description?

date.test = 'testing'
console.log(date) // Same as above, no description, but the property IS there.
console.dir(date) // Shows the object in a tree like it does with other objs.
// Note : The behavior for person is similar when used with a constructor instead of an object literal.

我知道,如果您排除new关键字而只说let date = Date(),它将返回一个字符串,所以我猜测我们在使用new Date()引用它时看到的值是对象的类型还是其构造函数的名称?无论如何,为什么像引用其他对象一样,或者至少以相同的格式引用对象时,为什么看不到对象的属性?

此外,如果您使用字符串插值,则IE:The current date is ${date}也会起作用,将日期正确替换为字符串,而如果我尝试使用上面的person对象将其破坏。使用构造函数而不是对象文字可以将[object Object]放在字符串中。

我知道在某些语言(如C#)中,您可以覆盖对象的ToString()方法,并且ToString()方法用作字符串插值的默认方法。与这里发生的事情类似吗?

也很好奇Date构造函数将返回什么。似乎它正在返回一个对象,并且如果您选中typeof(date),您会看到它是一个对象,但是它看起来并不像其他对象那样。至少在引用时没有。似乎可变日期既指向对象,又指向对象的值?

但是,如果您console.dir(date)日期,则它的构造函数名称似乎就是日期本身,就像某种动态的构造函数一样。奇。有什么想法吗?

tldr;为什么引用时Date对象的行为不同于其他对象?应该提到的是,它在REPL中像Node一样做同样的事情。

2 个答案:

答案 0 :(得分:1)

详细阐述Satpal的评论:

JavaScript的type coercion系统带有一些特定规则。您可以阅读关于它们的here

此类规则之一是对象(如果存在)通过其valueOf方法强制转换为数字。如果将对象强制转换为字符串,则调用其toString方法(如果存在)(如果不存在)-调用其valueOf并将结果从数字强制转换为字符串。如果这两种方法都不存在,则对象将强制为"[object Object]"的字符串。

Console.log和字符串插值需要一个字符串,因此您的Date对象被强制为一个字符串。请注意date.__proto__.toString方法。

现在说说构造函数:JavaScript中的一切都是对象,包括函数。因此,{strong>两者都是构造函数Date()和它通过new Date()返回的对象。此外,.__proto__.constructor属性实际上是引用构造函数,该函数的prototype属性用作给定对象的__proto__

为进一步说明问题,您应该阅读JavaScript的功能继承,如here所述。

答案 1 :(得分:-1)

看来,数据的dafault表示形式不会显示您的期望值,默认的表示方法与您想要的不匹配,如果您需要日期的替代表示形式,则需要编写类似于这个例子好极了 How to format a JavaScript date

function formatDate(date) {
  var monthNames = [
    "January", "February", "March",
    "April", "May", "June", "July",
    "August", "September", "October",
    "November", "December"
  ];

  var day = date.getDate();
  var monthIndex = date.getMonth();
  var year = date.getFullYear();

  return day + ' ' + monthNames[monthIndex] + ' ' + year;
}

console.log(formatDate(new Date()));

然后您要解决一些问题

function formatDate(date) {
                  //Checking if test attribute exist, in case it does
                  //I print it
   return date + (typeof date.test === 'undefined')?'':date.test;
}
date = new Date();
date.test = 'testing'
console.log(formatDate(date));