JavaScript 标准对象详解:类型检测、包装对象、Date与JSON

作者:小括号

时间:2026-10-30

浏览:132

本文深入解析JavaScript中的标准对象,涵盖使用typeof进行类型检测的陷阱,如null与Array均返回object。详细讲解Number、Boolean、String的包装对象及其比较差异。重点介绍Date对象处理日期时间、时区转换及时间戳的方法,并系统阐述JSON.stringify与JSON.parse在序列化与反序列化中的应用及高级参数用法。

文章目录

JavaScript对象类型与检测

在JavaScript语言体系中,所有数据本质上都是对象。

然而,部分对象的行为与其他对象存在显著差异。为了明确区分对象的类型,我们可以使用typeof操作符来获取其类型信息,该操作符始终返回一个字符串值。


typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'

从结果可以看出,number、string、boolean、function以及undefined具有独特的类型标识。需要特别注意的是,null的类型被判定为object,而Array的类型同样也是object。这意味着,如果仅依赖typeof操作符,我们将无法有效区分null、Array以及常规的{}对象。

包装对象机制

包装对象机制

number、boolean和string均存在对应的包装对象。在JavaScript中,字符串类型严格区分原始string类型与其包装类型。包装对象可以通过new关键字进行创建。


var n = new Number(123); // 123,生成了新的包装类型
var b = new Boolean(true); // true,生成了新的包装类型
var s = new String('str'); // 'str',生成了新的包装类型

尽管包装对象在视觉显示上与原始值完全一致,但其内部类型已转变为object。因此,当使用===运算符将包装对象与原始值进行比较时,结果始终为false。


typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false

因此,建议避免手动创建包装对象,尤其是针对字符串类型时更应谨慎使用。

Date对象与时区处理

日期处理

在JavaScript中,Date对象专门用于表示日期和时间信息。

若需获取系统当前时间,可执行以下代码。


var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳

需注意,当前时间由浏览器从本机操作系统获取,因此其准确性受用户系统时间设置影响,用户可将时间设定为任意值。

若需创建一个指定具体日期和时间的Date对象,可采用如下方式。


var d = new Date(2015, 5, 19, 20, 15, 30, 123);

一个值得注意的细节是,JavaScript中月份以整数表示,范围是0至11,其中0代表一月,1代表二月,依此类推。因此,若要表示六月,传入的参数应为5。这是JavaScript早期设计的一个特点,目前难以更改。

另一种创建指定日期和时间对象的方法是解析符合ISO 8601格式的字符串。


var d = Date.parse('2015-06-24T19:49:22.875+08:00');
d; // 1435146562875

该操作返回的并非Date对象,而是一个时间戳数值。不过,通过时间戳可以方便地将其转换为一个Date对象。


var d = new Date(1435146562875);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)

时区处理

Date对象表示的时间默认按浏览器所在时区显示,但我们既可以选择显示本地时间,也可以显示调整后的UTC时间。


var d = new Date(1435146562875);
d.toLocaleString(); // '2015/6/24 下午7:49:22',本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关
d.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT',UTC时间,与本地时间相差8小时

在JavaScript中进行时区转换时,只要传递的是number类型的时间戳,便无需手动处理时区转换问题。任何浏览器都能将时间戳正确转换为本地时间。

因此,最佳实践是仅传递时间戳,或从数据库中读取时间戳后,交由JavaScript自动转换为当地时间。

若需获取当前时间戳,可使用以下方法。


if (Date.now) {
  alert(Date.now()); // 老版本IE没有now()方法
} else {
  alert(new Date().getTime());
} 

JSON序列化与反序列化

JSON格式

在JSON标准中,主要包含以下几种数据类型。

•number:与JavaScript中的number类型完全一致;

•boolean:对应JavaScript中的true或false;

•string:对应JavaScript中的string类型;

•null:对应JavaScript中的null值;

•array:对应JavaScript中Array的表示方式,即[];

•object:对应JavaScript中{ ... }的表示方式。

此外,还包括上述类型的任意组合形式。

序列化操作

首先,我们将小明这个对象序列化为JSON格式的字符串。


var xiaoming = {
  name: '小明',
  age: 14,
  gender: true,
  height: 1.65,
  grade: null,
  'middle-school': '\"W3C\" Middle School',
  skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};

使用JSON.stringify()之后:


JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'

若希望输出结果更具可读性,可以添加参数以实现缩进输出。


JSON.stringify(xiaoming, null, ' ');

输出结果如下。


{
 "name": "小明",
 "age": 14,
 "gender": true,
 "height": 1.65,
 "grade": null,
 "middle-school": "\"W3C\" Middle School",
 "skills": [  "JavaScript",  "Java",  "Python",  "Lisp"
 ]
}

第二个参数用于控制如何筛选对象的键值。如果仅希望输出指定的属性,可以传入Array类型的数组。


JSON.stringify(xiaoming, ['name', 'skills'], ' ');

输出结果如下。


{
 "name": "小明",
 "skills": [  "JavaScript",  "Java",  "Python",  "Lisp"
 ]
}

还可以传入一个函数,使得对象的每个键值对都会先经过该函数处理。


function convert(key, value) {
  if (typeof value === 'string') {
    return value.toUpperCase();
  }
  return value;
}

JSON.stringify(xiaoming, convert, ' ');

上述代码示例将所有字符串属性值转换为大写形式。


{
 "name": "小明",
 "age": 14,
 "gender": true,
 "height": 1.65,
 "grade": null,
 "middle-school": "\"W3C\" MIDDLE SCHOOL",
 "skills": [  "JAVASCRIPT",  "JAVA",  "PYTHON",  "LISP"
 ]
}

若需更精确地控制小明的序列化过程,可以为xiaoming对象定义一个toJSON()方法,直接返回JSON序列化时应包含的数据。


var xiaoming = {
  name: '小明',
  age: 14,
  gender: true,
  height: 1.65,
  grade: null,  'middle-school': '\"W3C\" Middle School',
  skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
  toJSON: function () {
    return { // 只输出name和age,并且改变了key:
      'Name': this.name, 'Age': this.age
    };
  }
};
JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'

反序列化操作

获取到JSON格式的字符串后,可直接使用JSON.parse()将其转换为JavaScript对象。


JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45

JSON.parse()函数还可以接收一个函数作为参数,用于转换解析出的属性值。


JSON.parse('{"name":"小明","age":14}', function (key, value) {
  // 把number * 2:
  if (key === 'name') {
    return value + '同学';
  }
  return value;
}); // Object {name: '小明同学', age: 14}

以上关于JavaScript标准对象的讲解即为全部内容,希望能为读者提供参考。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章