Skip to main content

Javascript 数据类型

数据类型

与后端编程语言Java类似,Javascript数据类型分为基本类型(值类型)和引用类型(对象类型)。

基本类型

ES5定义基本类型有以下五类:

  • 字符串
  • 数值
  • 布尔
  • null
  • undefined

基本类型通常使用字面量来初始化,赋值过程会拷贝数据。

var s = "welcome to ssp1024.com"; // 字符串
var n = 1024; // 数值
var b = true; // 布尔
var user = null; // null
var foo = undefined; // undefined
var bar; // undefined

引用类型

除上面的基本类型外,其他数据都属于引用类型,也被称为对象类型。赋值操作是将指针复制了一份,指向的是同一个对象,可以通过任何一个引用来修改这个对象的值:

var foo = {"count": 0}
var bar = foo;
bar.count += 1;
console.log(foo); // {"count": 1}

Javascript 内置了一些常用的引用类型:

  • Object
  • Array
  • Function
  • RegExp
  • Date
  • Error

很多内置的引用类型也有字面量表达方式:

var o = {title: "Learn JS"}; // 对象
var a = ["ssp1024", "com"]; // 数组
var r = /\d{11}/g; // 正则表达式
function f() { // 函数
alert("welcome to ssp1024.com");
}

对象通常用构造函数来创建,Javascript 中任何函数都可以是构造函数,通常将构造函数首字母大写来区别于普通函数:

var o = new Object();
var a = new Array("ssp1024", "com");
var r = new RegExp("\\d{11}", 'g');
var f = new Function('alert("welcome to ssp1024.com")');
var d = new Date();
var e = new Error("illegal state");

注意Javascript中函数也是一个对象,可以用new方式创建函数,不过多数情况都是采用字面声明的方式。

自动装箱

Javascript 为 字符串、数值、布尔分别提供了封装类型:String, Number, Boolean,目的是方便类型的使用,使得操作基本类型和操作对象的方式一致。:

var n = 1024;
console.log(n.toFixed(2)) // "1024.00";

console.log("hello world".replace("world", "js")); // "hello js"

上面代码中直接在基本类型上调用方法,其实是执行引擎为基本类型创建了临时对象,上面代码等同于:

var n = 1024;
var tmp = new Number(n);
console.log(tmp.toFixed(2));
tmp = null;

var tmp = new String("hello world");
console.log(tmp.replace("world", "js"));
tmp = null;

所以不要对下面的情况感到意外:

var site = "ssp1024.com";
site.generator = "nextjs";
console.log(site.generator); // undefined

因为上面的代码会被执行引擎翻译成这样:

var site = "ssp1024.com";
var tmp = new String(site);
tmp.generator = "nextjs";
tmp = null;
console.log(site.generator); // undefined

另外对于这种情况你不应该感到意外:

var s = "welcome to ssp1024.com";
console.log(s instanceof String); // false
var S = new String("welcome to ssp1024.com");
console.log(S instanceof String); // true

var n = 1024;
console.log(n instanceof Number); // false
var N = new Number(1024);
console.log(N instanceof Number); // true

var b = true;
console.log(b instanceof Boolean); // false
var B = new Boolean(true);
console.log(B instanceof Boolean); // true

这是因为装箱操作只有在读取时才会触发,而 instanceof 操作符并没有读取任何东西,基本类型没有被包装成对应的封装类型。

日常编码尽量避免直接手动使用包装类型,比如这个代码会出乎很多人的意料:

var b = new Boolean(false);
if (b) {
console.log("condition is true"); // 这行代码会被执行
}

上面的条件判断结果为true,这是因为在Javascript中,一个非null对象在条件判断中总被视为true。

类型转换

TODO

相等性判断

Javascript 中有两种相等性判断:=====:其中 == 会将比较的对象转换成相同类型后比较;而===会进行严格相等性判断,包括对象的类型:

console.log("2" == 2); // true
console.log("2" === 2); // false

console.log(undefined == null); // true
console.log(undefined === null); // false

真值判断

console.log(!!0);               // false
console.log(!!1); // true
console.log(!!""); // false
console.log(!!"0"); // true

console.log(!!NaN); // false
console.log(!!null); // false
console.log(!!undefined); // false

console.log(!![]); // true
console.log(!!{}); // true
console.log(!!function(){}); // true

注意空对象 {} 、空数组 [] 都是非 null 对象,条件判断为 true

类型判断

typeof 操作符

对于基本类型,可以使用 typeof 运算符来获得其类型:

console.log(typeof "")          // "string"
console.log(typeof 1) // "number"
console.log(typeof true) // "boolean"
console.log(typeof null) // "object"
console.log(typeof undefined) // "undefined"

null 情况比较特殊,返回的是object

instanceof 操作符

对于引用类型,可以用 instanceof 运算符来判断对象是否是某个类型的实例:

console.log([] instanceof Array);               // true
console.log({} instanceof Object); // true
console.log(function(){} instanceof Function); // true
console.log(function(){} instanceof Object); // true