一 概述
1.1 类型
Javascript 数据类型分为值类型和引用类型,其中值类型包括字符串实体(例如:"string" ),数值实体(例如:100 )和布尔值实体(如:true )。而其他的复杂类型都属于引用类型,例如日期型( new Date() ),正则表达式(/a/gi, new RegExp("a", "gi") )数组( [1,2,3], new Array() )函数(function(){}, new Function() )和对象({a:"a", b:100}, new Object() )。这些都是Javascript 固有的数据类型,而用户自定义类型都属于引用类型(如:var Person = function(name){this.name=name;}; ),它们都只能使用new 关键字实例化为具体对象(new Person("hotoo") )。
为了理解Javascript 对象的类型,我们来看一些如下代码:
// test instanceof and typeof:
var instStr = ['"string"', '100' , 'true', '/a/g' , '[1,2,3]' , 'function(){}', '{}', 'null', 'undefined' ];
var inst = ["string", 100, true, /a/g, [1 ,2,3 ], function (){}, {}, null, undefined];
var ObjsStr = ["String", "Number" , "Boolean", "RegExp" , "Array", "Function", "Date" , "Object"];
var Objs = [String, Number , Boolean, RegExp, Array, Function, Date, Object];
jsoutInst ( "instanceof" , ObjsStr, Objs , instStr, inst);
function jsoutInst (methodName, tsStr , ts , osStr, os ){
document.write ("<table border='1'><tr>" );
document.write ("<td><strong>" +methodName+ "</strong></td>" );
for (var i= 0; i< tsStr. length; i++){
document.write ("<td>" +tsStr[i ]+"</td>" );
}
document.write ("</tr>" );
for (var i= 0; i< os. length; i++){
document.write ("<tr><td>" +osStr[i ]+"</td>" );
for (var j= 0; j< ts. length; j ++){
document.write ("<td>" +(os[i ] instanceof ts[j]? "<strong>true</strong>" :"false")+"</td>" );
}
document.write ("</tr>" );
}
document.write ("</table><br />" );
}
var typesStr = ["string", "number" , "boolean", "array" , "function", "date", "object" , "undefined"];
jsoutType ( "typeof" , typesStr, instStr , inst);
function jsoutType (methodName, tsStr , osStr , os){
document.write ("<table border='1'><tr>" );
document.write ("<td><strong>" +methodName+ "</strong></td>" );
for (var i= 0; i< tsStr. length; i++){
document.write ("<td>" +tsStr[i ]+"</td>" );
}
document.write ("</tr>" );
for (var i= 0; i< os. length; i++){
document.write ("<tr><td>" +osStr[i ]+"</td>" );
for (var j= 0; j< tsStr. length; j ++){
document.write ("<td>" +(typeof os[ i] == tsStr[ j]?"<strong>true</strong>" :"false" )+"</td>" );
}
document.write ("</tr>" );
}
document.write ("</table><br />" );
}
上面的代码很简单,第一个函数判断对象实例是否是某个类的实例(instanceof ),第二个函数对比对象实例是否与某类型(typeof )相等,他们将输出两个表格,我们来对比一下(为了方便阅读,这里将说明插在相应表格下。 )。
instanceof | String | Number | Boolean | RegExp | Array | Function | Date | Object |
"string" | false | false | false | false | false | false | false | false |
100 | false | false | false | false | false | false | false | false |
true | false | false | false | false | false | false | false | false |
/a/g | false | false | false | true | false | false | false | true |
[1,2,3] | false | false | false | false | true | false | false | true |
function(){} | false | false | false | false | false | true | false | true |
{} | false | false | false | false | false | false | false | true |
null | false | false | false | false | false | false | false | false |
undefined | false | false | false | false | false | false | false | false |
通过(instanceof )这个表格可以看出,值类型( "string", 100, true 等)不是任何对象的实体(instance ),而引用类型(/a/g, [1,2,3], function(){} 和 {} )既是本身类型的实体,又是其父类型的实体(所有类型都继承自Object 类型)。
所有通过引用类型(包括值类型的wrapper 类String, Number 和 Boolean )new 出来的对象,都是其对应类和其父类(这里是Object )的实例。
虽然值类型不是其对应wrapper 类的实例,但是值类型却可以直接使用其wrapper 类的属性和方法,就如同值类型是其 wrapper 类的实例一样。例如:"ABC".toLowerCase() 。
typeof | string | number | boolean | array | function | date | object | undefined |
"string" | true | false | false | false | false | false | false | false |
100 | false | true | false | false | false | false | false | false |
true | false | false | true | false | false | false | false | false |
/a/g | false | false | false | false | false | false | true | false |
[1,2,3] | false | false | false | false | false | false | true | false |
function(){} | false | false | false | false | true | false | false | false |
{} | false | false | false | false | false | false | true | false |
null | false | false | false | false | false | false | true | false |
undefined | false | false | false | false | false | false | false | true |