一.六种数据类型
五种原始类型:number、string、boolean、null、undefined
一种对象类型:object,它包括Function、Array、Date等等
二.隐式转换
“37”-7,结果:30
“37”+7,结果:377
var x='The answer is ' + 42;结果:'The answer is 42'
巧用+/-规则转换类型,如 num-0:转换成数字类型;num+'':转换成字符串类型
“1.23”==1.23,0==false,null==undefined这些是相等的;new Object()==new Object(),[1,2]==[1,2]这些对象类型是不相等的。
a===b:类型不同,返回false,类型相同:null === null,undefined === undefined,NaN!=NaN,new Object != new Object
a==b:类型相同,同===;类型不同,尝试类型转换和比较:
null==undefined 相等 number == string 转number 1=="1.0"//true boolean == ? 转number 1==true//true object == number | string 尝试对象转为基本类型 new String('hi') == 'hi' //true,其它:false
三.包装对象
在JavaScript中,当尝试将一个基本类型以对象方式使用时,如访问它的length属性,给它增加一些属性,JavaScript会很智能的将这基本类型包装成相应的对象类型,相当于new。
当a.length返回或a.t设置以后,这个临时对象会被销毁掉,数字、boolean同理,通过(123).toString()能将其转换成字符串也是类似的原理。
四.类型检测
1.typeof
typeof会返回一个字符串,它非常适合函数类型和基本类型的判断。
typeof 100"number" typeof true"boolean" typeof function"function" typeof(undefined)"undefined" typeof new Object()"object" typeof [1,2]"object" typeof NaN"number" typeof null"object"
2.instanceof
判断对象类型更适合用instanceof,它是基于原型链判断的操作符。希望左操作数是一个对象,如果不是一个对象,将直接返回false;希望右操作数是一个函数对象(函数构造器),如果不是的话,就会抛出TYPE ERROR异常。
原理:判断左边的操作数的原型链上是否有右边这个构造函数的prototype属性。
[1,2] instanceof Array === true new Object() instanceof Array === false
注意:不同window或iframe间的对象类型检测不能使用instanceof。
3.Object.prototype.toString
Object.prototype.toString.apply([]) ==="[object Array]" Object.prototype.toString.apply(function(){}) ==="[object Function]" Object.prototype.toString.apply(null) ==="[object Null]" Object.prototype.toString.apply(undefined) ==="[object Undefined]"
注意:IE6/7/8 Object.prototype.toString.apply(null)返回"[object Object]"。
4.constructor
任何一个对象都有一个constructor属性(实际上是继承自原型的),constructor会指向构造这个对象的构造函数,但由于constructor可以被改写的,使用的时候需小心。
5.duck type
如不知道这个对象是不是数组,可以判断它的length是不是数字,是不是有join、push等方法。通过一些特征判断这个对象是否属于某个类型。
6.类型检测小结:
typeof:适合基本类型及function检测,遇到null失效。
Object.prototype.toString:通过{}.toString拿到,适合内置对象和基本元素类型,遇到null和undefined失效(IE678等返回[object Object])。
instanceof:适合自定义对象,也可以用来检测原生对象,在不同iframe和window间检测时失效。
五.练习
请在index.html文件中,编写arraysSimilar函数,实现判断传入的两个数组是否相似。具体需求:
1. 数组中的成员类型相同,顺序可以不同。例如[1, true] 与 [false, 2]是相似的。
2. 数组的长度一致。
3. 类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数,日期, window.
当以上全部满足,则返回"判定结果:通过",否则返回"判定结果:不通过"。
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=gb18030">
<title>Untitled Document</title>
</head>
<body>
<script type="text/javascript">
/*
* param1 Array
* param2 Array
* return true or false
*/
function arraysSimilar(arr1, arr2){
//判断边界
if(!(arr1 instanceof Array) || !(arr2 instanceof Array)) {
return false;
}
//判断长度
if(arr1.length !== arr2.length) return false;
var i=0,
n=arr1.length,
countMap1 = {},
countMap2 = {},
t1,t2,
TYPES = ['string', 'boolean', 'number','undefined','null','function','date','window'];
for(;i<n;i++) {
t1 = typeOf(arr1[i]);
t2 = typeOf(arr2[i]);
if(countMap1[t1]) {
countMap1[t1]++;
}else {
countMap1[t1]=1;
}
if(countMap2[t2]) {
countMap2[t2]++;
}else {
countMap2[t2] = 1;
}
}
function typeOf(ele) {
var r;
if(ele === null) {
r='null';
}else if(ele instanceof Array) {
r='array';
}else if(ele === window) {
r='window';
}else if(ele instanceof Date) {
r='date';
}else {
r=typeof ele;
}
return r;
}
for(i=0,n=TYPES.length;i<n;i++) {
if(countMap1[TYPES[i]] !== countMap2[TYPES[i]]) {
return false;
}
}
return true;
}
</script>
<script src="testData.js"></script>
</body>
</html>
testData.js
var result=function(){ //以下为多组测试数据 var cases=[{ arr1:[1,true,null], arr2:[null,false,100], expect:true },{ arr1:[function(){},100], arr2:[100,{}], expect:false },{ arr1:[null,999], arr2:[{},444], expect:false },{ arr1:[window,1,true,new Date(),"hahaha",(function(){}),undefined], arr2:[undefined,(function(){}),"okokok",new Date(),false,2,window], expect:true },{ arr1:[new Date()], arr2:[{}], expect:false },{ arr1:[window], arr2:[{}], expect:false },{ arr1:[undefined,1], arr2:[null,2], expect:false },{ arr1:[new Object,new Object,new Object], arr2:[{},{},null], expect:false },{ arr1:null, arr2:null, expect:false },{ arr1:[], arr2:undefined, expect:false },{ arr1:"abc", arr2:"cba", expect:false }]; //使用for循环, 通过arraysSimilar函数验证以上数据是否相似,如相似显示“通过”,否则"不通过",所以大家要完成arraysSimilar函数,具体要求,详见任务要求。 for(var i=0;i<cases.length;i++){ if(arraysSimilar(cases[i].arr1,cases[i].arr2)!==cases[i].expect) { document.write("不通过!case"+(i+1)+"不正确!arr1="+JSON.stringify(cases[i].arr1)+", arr2="+JSON.stringify(cases[i].arr2)+"的判断结果不是"+cases[i].expect); return false; } } return true; }(); document.write("判定结果:"+(result?"通过":"不通过"));
打开index.html,效果如下: