JavaScript类型转换机制及各类型检查方法

JavaScript类型转换机制及各类型检查方法

    在JavaScript中,我们通常会碰到有关于值比较的问题。由于JavaScript类型转换机制的存在,往往会遇到一些尴尬的问题。比如我们会遇到这样的问题 alert(true == 1); // 结果返回true 以及 alert([] == 0); // 结果依旧返回true 等等问题。在介绍JavaScript类型转换机制之前,首先我们必须了解一下JavaScript的原始值及引用对象。

1 JavaScript的原始值及引用对象

    JavaScript的值分为两种类型:原始类型和引用类型(也称做对象)。
        原始类型包括:字符串、数字、布尔值、null和undefined
        引用类型包括:数组和函数

1.1 原始类型与引用类型的区别

    1、原始类型的值是不可变的,引用类型的值是可变的。

        var str1 = "hello";    // 首先存在一个为"hello"的字符串,我们使用变量str1接收
        var str2 = str1;    // 然后我们将str1赋值给str2
        str1 = str1.toUpperCase();    // 接着我们调用一下字符串的方法,将字符串中的字母全部大写
        alert(str2);            // 最后我们输出一下str2 结果依旧是 hello


        当然举这样一个例子,事实上是说明,字符串中所有的方法看上去返回一个修改后的字符串,实际上返回的是一个新的字符串。对于数字和布尔值就更加明显了--改变数字的值本身就说不通。
        
    2、原始类型的比较,只有它们的值相等的时候它们才相等。对于字符串来说就不太好理解。
        JavaScript规定字符串,当前仅当它们的长度相等及每个索引的字符都相等时,JavaScript才认为他们相等。而引用类型的比较:当且仅当它们引用同一个对象时,它们才相等。那么,即使两个对象包含同样的属性及相同的值,它们也不一定是相等的。
 

var a = {x:1};
var b = {x:1};
alert("比较1:" + (a === b)); // 结果返回false
			
var a = [];
var b = [];
alert("比较2:" + (a === b)); // 结果返回false
			
var a = [];
var b = a;
var c = b;
alert("比较3:" + (a === b)); // 结果返回true

2 JavaScript类型转换机制

    了解了JavaScript的值的类型之后,我们再来看JavaScript类型转换机制。JavaScript会根据需要自行转换类型。这一点我们从以下示例就可以看出。

var str = "30";
str = str * 10;    // 因为执行乘法运算,乘法的两边都应该是数字类型,JavaScript会根据需要将str转换为数字类型
alert(str);    // 结果返回300

var str2 = 30;
str2 = str2 + "10";    // 因为执行+运算,因为+的一遍包含字符串"10",因此我们可以将+看出连接符,JavaScript会根据需要将str转换为字符串
alert(str2);    // 结果返回3010


            
2.1 JavaScript各类型之间的转换对应表 

根据《JavaScript权威指南》,以下表格说明了各类型之间的转换。空单元格表示不必要也没有执行转换。

转换为
 字符串数字布尔值对象
undefined"undefined"NaNfalsethrows TypeError
null"null"0falsethrows TypeError
true"true"1 new Boolean(true)
false"false"0 new Boolean(false)
""(空字符串) 0falsenew String("")
"1.2"(非空,数字) 1.2truenew String("1.2")
"one"(非空,非数字) NaNtruenew String("one")
     
0"0" falsenew Number(0)
-0"0" falsenew Number(-0)
NaN"NaN" falsenew Number(NaN)
Infinity"Infinity" truenew Number(Infinity)
-Infinity"-Infinity" truenew Number(-Infinity)
1(无穷大,非0)"1" truenew Number(1)
     
{}(任意对象)具体见下文具体见下文true 
[](任意数组)""0true 
[9](一个数字元素的数组)"9"9true 
['a'](其他数组)使用join()方法NaNtrue 
function(){}(任意函数)具体见下文NaNtrue 


    说明:
            (1)原始值到对象的转换非常简单。原始值通调用String(),Number(),或Boolean()构造函数,转换成为它们各自的包装对象。
            (2)null和undefined属于例外,当它们用在期望是一个对象的地方时,都会造成一个类型错误(TypeError)异常,而不会执行正常的转换
            (3)对象到原始值的转换比较复杂。具体请看后续分析。

2.2 显示类型转换

    通过调用Boolean()、Number()、String()或Object()函数显示的将数据转换为期望的类型的方法。

Number("1") ==> 1
 String("true") ==> "true"
Boolean([]) ==> true
Object("3") ==> new Number("3") 

     需要注意的是:如果试图将null或undefined转换成为对象,则会报类型错误(TypeError)具体如上表所示。 如果是Object()函数,则会返回一个新创建的空对象

2.3 隐式类型转换

     JavaScript中的某些运算符会做隐式转换, 例如var x = "30";  +x; ==> 等价于 x-0。像这种通过JavaScript中的某些运算符达到数据类型转换目的的方法称之为隐式转换。

x + ""; 	// 等价于String(x);
+x;			// 等价于Number(x);或 x - 0;
!!x;		// 等价于Boolean(x);需要注意的是双感叹号

2.4 对象转换为字符串

    1、 如果对象具有toString()方法,则调用这个方法,如果它的返回值是一个原始值,JavaScript将这个值转换为字符串(如果其本身不是字符串),并返回这个字符串结果。详细的转换对比上表。

    (1)数组转换为字符串

    数组转换为字符串时,调用toString()方法,该方法将数组转换成一个字符串,并在元素间添加逗号后结合成结果字符串,例如:["1","2","3"].toString(); // ==> 1,2,3

var a = ["1","2","3"];
var b = "1,2,3";
alert(a == b);

    (2)函数类转化为字符串

     函数类转换为字符串时,通常toString()方法实际返回的是这个函数的实现定义表现方式。Eg:(function(x){f(x);}).toString; ==> // function(x){f(x);}

var a = "function(x){f(x);}";
var b = function(x){f(x);};
var c = function(x){
    f(x);
};
console.log("a == b:" + (a == b));
console.log("a == c:" + (a == c));
console.log(c.toString());


        

    2 、 如果对象没有toString()方法,或者这个方法不返回一个原始值,那么JavaScript会调用valueOf()方法。如果这个方法存在JavaScript则会调用它。如果返回值是原始值,JavaScript会将这个值转换为字符串(如果其本身不是字符串的话),并返回这个字符串结果。

var obj = {
    name:"",
    age:12,
    valueOf:function(){
        return "this is valueOf()"
    }
};
alert("查看调用的方法:" + obj);

    备注:根据《JavaScript权威指南》说明,理论上应该先调用toString(),如果没有则调用valueOf()方法,而事实上则先调用valueOf()方法,然这一点我很费解。知道原因的朋友,麻烦留言一下。具体如下:

var obj = {
	name:"",
	age:12,
	toString:function(){
		return "this is toString()"
	},
	valueOf:function(){
		return "this is valueOf()"
	}
	
};
alert("查看调用的方法:" + obj);

 

    3、否则, 无法从toString()或valueOf()获得一个原始值。因此这时将抛出一个类型错误异常。

var obj = {
	name:"",
	age:12,
	toString:function(){
		return new Object();
	},
	valueOf:function(){
		return new Object();
	}
	
};
alert("查看调用的方法:" + obj);

2.5 对象转换为数字

对象转换为数字的过程与到字符串类似,只是它会首先尝试使用valueOf()方法。

   1、如果对象具有valueOf()方法,则调用这个方法,如果它的返回值是一个原始值,JavaScript将这个值转换为数字(如果其本身不是数字),并返回这个数字。详细的转换对比上表。

    2 、 如果对象没有valueOf()方法,或者这个方法不返回一个原始值,那么JavaScript会调用toString()方法。如果这个方法存在JavaScript则会调用它。如果返回值是原始值,JavaScript会将这个值转换为数字(如果其本身不是数字的话),并返回这个数字。

    3、否则, 无法从toString()或valueOf()获得一个原始值。因此这时将抛出一个类型错误异常。

 

3 “==”与“===”

在讲述各类型比较之前,我们先了解一下“==”(相等运算符)与“===”(恒等运算符)

3.1 “===”

严格相等运算符“===”,也称做恒等运算符,它用来检测两个操作数是否严格相等。

恒等运算符“===”,首先比较两个操作数数据类型是否相同,然后比较这两个值,比较过程中没有任何类型转换:

(1) 如果两个值类型不同,则它们不同。

(2)如果两个值都是null或者都是undefined,则他们相等。

(3)如果两个值都是布尔值true或者都是false,则他们相等。

(4)如果其中一个值是NaN,或者两个值都是NaN,则他们不相等。NaN和其他任何值都不相等,包含它本身。通过x!==x判断x是否为NaN,只有当x为NaN时,这个表达式才为true。

(5)如果两个值都为数字且数值相等,则它们相等。如果一个值是0,另一个值是-0,它们同样相等。

(6)如果两个值为字符串,且所含对应为上的16位 数完全相等,则他们相等。如果他们的长度或内容不同,则它们不相等。两个字符串可能完全意义上一样且显示出的字符也一样,但是具有不同编码的16位值,则他们不等。

(7)如果两个引用值指向同一个对象、数组、函数,则他们相等。如果指向不同的对象,则他们不等,尽管两个对象具有完全一样的属性。

3.2  “==”

相等运算符“==”,用来检测两个操作数是否相等,不同意恒等运算符“===”的是,相等运算符“==”,只比较两个操作数的值是否相等,如果两个操作数的数据类型不同,那么相等运算符“==”会尝试做做隐式类型转换,然后进行比较。

(1)如果两个数据类型相同,则和恒等运算符所述规则一样。如果严格相等,那么比较结果相等,如果不严格相等,则比较结果为不相等。

(2)如果两个操作数的数据类型不同,相等运算符“==”也可能认为他们相等。检查相等会遵循如下规则和类型转换:

    ①如果一个值是null,另一个是undefined,则他们相等。

    ②如果一个值是数字,另一个值是字符串,则先将字符串转换为数字,然后使用转换后的值进行比较

    ③如果其中一个值是true,则将其转换成1再进行比较。如果其中一个值是false,则将其转换成0再进行比较。

    ④如果一个值是对象,另一个值是数字或字符串,则现将对象转换成原始值(转换规则如上述),然后进行比较。

    ⑤其他不同类型之间的比较不相等。

3.3 总结

    恒等运算符“===”

        数据类型相同时:

             原始值直接比较值,值相等则他们相等,需要注意的是String类型必须具有相同编码的16位值。

             引用类型,需要注意是否指向同一个对象、数组、函数。Eg: var a = [1,2,3];var b = [1,2,3]; a === b; 结果为false。

var a = [1,2,3];
var b = [1,2,3];
alert("a === b:" + (a === b));

 

 

    数据类型不同时:直接返回false;

 

相等运算符“==”

     数据类型相同时,比较结果与恒等运算符比较结果相同。

     数据类型不同时

         (1)null与undefined除与自己相等外,他们彼此也相等,即 null == undefined,结果返回为true。

         (2)如果都是原始值,会将其他类型转换为数字,然后进行比较。

         (3)如果其中一个类型是对象,则将对象转换为原始值,然后在进行比较。

 

....未完

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丨Anna丨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值