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