JavaScript复习笔记(3)——数据类型(null、undefined、NaN)与深度克隆

JavaScript中的数据类型:Number、Boolean、String、Object、Function

但是此外还有一些容易混淆的类型如null、undefined、NaN、Array的概念

function showDataType(){
	console.log("Number: "+typeof 1);
	console.log("String:"+typeof "str");
	console.log("Boolean:"+typeof true);
	console.log("Null:"+typeof null);
	console.log("Undefined:"+typeof undefined);
	console.log("NaN:"+typeof NaN)
	var person={name:"lcy"};
	console.log("Object:"+typeof person);
	var arr = ["1","2"];
	console.log("Array:"+typeof arr);
	console.log("Object Array:"+Object.prototype.toString.call(arr) )
	console.log("Function:"+typeof showDataType);
}

上面这段在控制台的输出结果为:

Number:number
String:string
Boolean:boolean
Null:object
Undefined:undefined
NaN:number
Object:object
Array:object
Object Array:[object Array]
Function:function 

总结:

  1. null是特殊的Object
  2. NaN是特殊的number
  3. Array属于Object,但是通过访问内部属性的方式还是可以进行类型判断

进一步对null、undefinde、NaN进行解析:

function showDataType2(){
    console.log(null===null);//true
    console.log(undefined===undefined);//true
    console.log(NaN===NaN);//false
    
    console.log(null==undefined);//true
    console.log(null===undefined);    //false
    console.log("!null: "+!null);//true
    console.log("!undefined: "+!undefined);//true
    console.log(NaN==undefined);//false
    console.log(NaN===undefined);//false
    console.log(NaN==null);//false
    console.log(NaN===null);//false
    console.log(null instanceof Object)//false
}

总结:

  1. NaN与自己本身也不相等
  2. null和undefined虽然不属于boolean类型,但是却可以转换成boolean类型进行判断,并且null==undefined是true的
  3. null的typeof是Object,null却不是Object子类的实例

同时,我们对这些数据类型的constructor也进行一次分析

function showDataType(){
    /*constructor*/
    var obj=1;
    console.log("Number:"+obj.constructor);//Number
    obj="1";
    console.log("String:"+obj.constructor);//String
    obj=true;
    console.log("Boolean:"+obj.constructor);//Boolean
    obj=null;
    //console.log("Null:"+obj.constructor);//报错
    obj=undefined;
    //console.log("Undefined:"+obj.constructor);//报错
    obj=NaN;
    console.log("NaN:"+obj.constructor)//Number
    obj = {name:"lcy"};
    console.log("Object:"+obj.constructor);//Object
    obj = ["1","2"];
    console.log("Array:"+obj.constructor);//Array
    console.log("Function:"+showDataType.constructor);//Function
    
    /*valueOf*/
    var obj=1;
    console.log("Number:"+obj.valueOf());//1
    obj="1";
    console.log("String:"+obj.valueOf());//1
    obj=true;
    console.log("Boolean:"+obj.valueOf());//true
    obj=null;
    //console.log("Null:"+obj.valueOf());//报错
    obj=undefined;
    //console.log("Undefined:"+obj.valueOf());报错
    obj=NaN;
    console.log("NaN:"+obj.valueOf())//NaN
    obj = {name:"lcy"};
    console.log("Object:"+obj.valueOf());//[object Object]
    obj = ["1","2"];
    console.log("Array:"+obj.valueOf());//1,2
    console.log("Function:"+showDataType.valueOf());//输出了整个方法的代码
}

 

了解了多种数据类型以及差别之后,回过头再来看深度克隆的问题,在深度克隆中比较容易出现的瑕疵有:

1.对null undefined类型的克隆

2.克隆后对prototype添加非常规属性,克隆对象与原对象能否区分开来

3.对Array的克隆

function cloneObject(obj)
{
    //null & undefined
    var o;
    if(!obj){
        return obj;
    }
    else{
        //array
        if(Object.prototype.toString.call(obj)=="[object Array]"){
            return obj.slice(0)//clone arrry
        }
        //object
        else if(typeof obj ==="object"){
            o = new obj.constructor();
            for(var key in obj){
                if(!obj.hasOwnProperty(key)){
                    o[key] = cloneObject(obj[key]);
                }
            }
        }
        //function
        else if(typeof obj==="function"){
            return obj;
        }
        //number,string,boolean,
        else{
            o = new obj.constructor(obj.valueOf());
        }
    }
    return o;    
    
}

对以上方法进行测试:

function Obj1(){
    this.a = 1 ;
    this.b = null;
    this.c = [1,2,3,4];
    this.d;
    this.fn = function(){alert("clone function")};
}
Obj1.prototype.arr = [1,2,3,4];
var o1 = new Obj1();
var o2 = cloneObject(o1);
console.log(o1);
console.log(o2);
o1.c[0]=100;
o1.d=new Array(1,5,7);
o1.fn = function(){alert("clone function success")};
console.log(o1);
console.log(o2);

o1.arr[0] = 100;
console.log(o1.arr);
console.log(o2.arr);

输出结果如图所示:

那么基本上是克隆成功了,虽然方法看上去有点臃肿,但是逻辑上比较清晰。

注:

克隆数组的方法:

1.新建一个数字,逐值赋值

2.利用slice()方法

3.利用contact与一个空数组进行合并


 

posted @ 2014-09-22 16:35  苜冉冉  阅读(303)  评论(0编辑  收藏  举报