JavaScript欲速则不达—原始值及原始值的隐式类型转换

我们知道在JavaScript中声明一个变量只需要要使用 var 操作符,后跟变量名,该变量就存在了,而该变量可以用来保存任何类型的数据。就是说变量的类型是根据所赋值的类型来决定自己的类型,所以一个变量到底是什么类型,不取决于变量定义本身,取决于它所包含的数据。数据类型决定着变量类型。

JavaScript中有五种原始类型值:Undefined、Null、Boolean、String、Number 。本文不讨论对象(包括数组和函数)

Undefined类型

Undefined类型只有一个值,即 undefined,中文意思就是未定义的意思,所以就跟这个单词所说一样,JavaScript中 未初始化 或者 未申明 的变量。而如果执行一个未申明的变了会导致一个错误,只能对其使用 typeof 操作符检测,如下

var name;
//var article
alert(name);//"undefined"
alert(article);//产生错误
alert(typeof name );//"undefined"
alert(typeof article );//"undefined"
未初始化和未申明的变量,typeof 运算符不会区分

虽然未初始化 或者 未申明本质上有区别,但是对于 Undefined类型 我们没有实际的操作价值。 Undefined类型 只有一个 undefined 值,另一种只有一个值的类型是 Null,值也就是它的字面量 null (首字母大写才是它们的类型,小写是他们的值)。

null 值从逻辑角度来看表示一个空对象指针,所以用 typeof 操作符检测null值会返回 object 。但是 Null 是没有值的,所以 Null不是任何数据类型的对象实例,因此alert(null instanceof Object); 返回false。

w3school上说:“值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。”。null==undefined为真,但是null===undefined为假说明他们不是完全相等的。

var eq;
alert(eq==null); //ture
alert(eq===null);//false
alert(typeof null); //弹出 'object'
alert(null instanceof Object);//false
null与undefined大不同

注意:尽管null值和undefined有这样的关系,但是他们的用途大不相同。用 typeof 操作符检测 Null 会返回 object,所以 null值一般保存还没真正保存对象的变量,如你声明var doc = null为将来保存一个节点对象; 而undefined则没这个必要。

Boolean 类型

Boolean 类型是JavaScript中使用最多的一种类型,它只有两个字面量值:true和false。虽然true不一定等于1,false不一定等于0,但是JavaScript会在必要时将0转换成false。注意:在基本类型中undefined、null、””、0以及无关键字的数组等同于false的布尔值都是false,其他都是true。

原始的Boolean值和Boolean对象是有区别的,不要相互混淆。Boolean对象是对Boolean值的一个封装,是对一个值为true或false的Boolean对象,是不同概念的。

Number 类型

JavaScript中数值型是不区分整数和浮点数的,所以只要该数值包含一个小数点,并且小数点后面有至少一位数字,就是浮点数集。数值还可以通过十进制、八进制、十六进制的字面量表示,最基本的十进制。其中,八进制中如果字面值超出范围,那么后面的数值就当作十进制数值解析。如下:

var octalNum1 = 070 //八进制57,第一位是0表示按照8进制解析
var octalNum1 = 079//无效的八进制-解析成十进制79
var octalNum1 = 0x1f //十六进制31,0x开头表示安装十六进制解析
//其他格式则一律十进制
十进制、八进制、十六进制表示的数值

特殊的 Number 值有正负Infinity和NaN。

特殊的 Number 值NaN

是 Not a Number 的缩写,NaN表示某个值不是数值,但是其本身是特殊的数字值()。

NaN 与其他数值进行比较的结果总是不相等的,包括它自身在内。因此,不能用 Number.NaN 比较来检测一个值是不是数字,只能调用 isNaN() 来判断是不是 NaN。

var a = "234" ;
a = a.replace(/(^[//s]*)|([//s]*$)/g, "");
if( a !="" && !isNaN( a ) )
{
    a = eval( a ) //如果是数字
}
else
{
    a = null  //如果不是数字
}
判断是不是数字值

特殊的Infinity值

因为JavaScript中的数值是有限的,所以如果某个数值超出数值范围,那么这个数值将被自动转换成特殊的Infinity值。如果这个数是正,则会被表示成Infinity(正无穷大);这个数值是负无穷大,则会表示成-Infinity(负无穷大)。可以对任何数调用 isFinite()方法,以确保该数不是无穷大,返回true则是在范围之内;false则是范围之外

String类型

字符串(String)可以包含在双引号或者单引号里,字符串中的每个字符都有特定位置,所以可以通过访问length属性取得字符串的长度,首字符从位置 0 开始。因为在JavaScript中服从Unicode编码,所以不管是中文还是英文,length返回的都是字符串的个数。

特殊的字符串字面量(转义字符)

  1. \n  换行
  2. \t  制表
  3. \b  空格
  4. \f  回车
  5. \\  反斜杠
  6. \’  单引号
  7. \”  双引号

类型转换

转换成数值方法

var x = 3;
var y = x + "2";
var z = x + 2;
alert(x + "2")//输出32
alert( x + 2)//输出5

一般使用3个函数,eval()暂且不论。

  • parseFloat()和parseInt()只要开头是数字的非数值就能正确返回,有容错性。
  • parseFloat()和parseInt()遇到首字母是字母则返回NaN,不过parseInt()有两个参数,第二个参数决定将以几进制解析数值(16进制,你懂的)。
  • parseInt() 转换成整数,如果有小数点,只认识小数点前的数字值;parseFloat() 能转换浮点数,不过只能识别一个小数点,就是说第二个小数点和之后的字符无效。
  • Number()没有容错性,但是也有特殊情况:布尔值true会返回1,false值、null值、空字符串会返回0;其他只要不是阿拉伯数字统统返回NaN。
  • parseFloat()和parseInt()只处理字符串,Number()可以处理任何类型的。
var num1 = '1234abc';
var num2 = true;
var num3 = '4.5';
alert(parseInt(num1)); //输出1234,parseFloat输出一样
alert(Number(num1)); //输出NaN
alert(parseInt(num2));//输出NaN,parseFloat输出一样
alert(Number(num2));//输出1
alert(parseInt(num3));//输出4
alert(Number(num3));//输出4.5,parseFloat输出一样
数字值转换

转换成字符串方法

数值、布尔值、对象、字符串以及所有对象都有tostring()方法(null和undefined没有tostring()方法)。

ps:tostring()方法在调用数值的时,可以传递参数来决定以几进制返回字符串。规律如下:

  • 如果值有tostring()方法,则调用该方法
  • 如果值是null,则返回”null”
  • 如果值是undefined,则返回”undefined”

JavaScript中的隐式类型转换

var x = 4;
var y =x+"";
var a = '11';
a = a - "";
alert(typeof a);//number
alert(typeof x);//number
alert(typeof y);//string
alert(a);//11
alert(x + "3");//43
alert(x + 3);//7
alert("3"*x);//12

以上转换过程就是隐式转换的。

如上诉例子所示,”+”,”-“,”*”当然也包括”/”在运算中可以隐式得转换类型 。”+” 可以很方便的将Number转换成String;而”-“,”*”,”/”跟”+”正好相反,能将String类型转换成Number类型。

如果上下文需要boolean型的值,则引擎会自动将对象转换为boolean类型。转换规则:如果该对象非空,则转换为true,否则为false,所以null==undefined。

if跟while会把obj隐式的转换成Boolean类型;for in定义对象字面量时发生从标识符到字符串的隐式转换。

alert也会隐式类型转换。

假如给String原型上添加了个fn方法,该方法返回this,我们知道this可以理解成当前类的实例对象,既然是对象那么typeof a.fn()自然返回是object了。那么alert()该方法会是什么情况:

String.prototype.fn = function(){return this};
var a = 'hello';
alert(typeof a.fn()); //object
alert(a.fn());  //hello

很明显,alert() 语句隐式的将其转换成了字符串“hello”。

在基本数据类型隐式转换中做了如下几步骤:

  1. 基本类型值会先临时包装相对应的包装对象
  2. 采用操作方法后,直接销毁该对象(这里说的对象指一种类型,不是对象本身)。
var sr1 = "xiaobei";
var sr2 = sr1.substring(2);
alert(sr2); //aobei
sr1.color ="red";
alert(sr1.color);//undefined

以上代码说明,当调用substring方法来操作String基本类型时,JavaScript会自动包装一个临时的String对象,然后获取该对象的使用substring方法,调用完之后这个临时的对象就被摧毁,所以我们想给他增加一个color属性时,alert出来的是undefined。

因为是JavaScript自己创建基本包装对象的,所以我们叫它影式转换,跟显式的调用Boolean、Number跟String来创建包装对象对立。那么能影式将将基本类型转换成基本类型对象,JavaScript也可以隐式的将对象转换为基本类型,如下几步骤:

首先通过调用对象的valueOf()方法来取得对象的值,如果和上下文的类型匹配,则使用该值。如果valueOf取不到值的话,则需要调用对象的toString()方法,而如果上下文为数值型,则又需要将此字符串转换为数值。valueOf()的作用是,将一个对象的值转换成一种合乎上下文需求的基本类型,toString()则名副其实,可以打印出对象对应的字符串,当然前提是你已经“重载”了Object的toString()方法。

基本包装对象

因为有了基本包装类型,所以JavaScript中的基本类型值可以当作对象来访问,三种基本包装类型分别是:

  • Boolean(value) – 把给定的值转换成 Boolean 型;
  • Number(value) – 把给定的值转换成数字(可以是整数或浮点数);
  • String(value) – 把给定的值转换成字符串;

以上3中方法其实就是继承了valueOf()、toLocaleString()、和toString()方法,并且都重写了这些方法。这三种方法可以转换任何类型的数据。

JavaScript复杂数据类型(引用类型)包括数组(Array)、函数(function)、原始类型的引用类型(既通过Boolean(),Number(),String()创造的对象)以及JavaScript定义的一些专用对象类。其中函数(Function)是一个可调用的对象,不只是一组数据集合,是一段可执行的代码块。而且一个函数如果作为一个对象的属性(我们平时叫方法 method )。所以我觉得这就是为什么 typeof 操作符检测函数会返回 function 不返回 object的原因,作者是想告诉我们他们之间大不同。JavaScript的复杂类型这里就不详细介绍了。

本文源链接:http://www.html5jscss.com/js-data-type.html

转载请注明《JavaScript欲速则不达—原始值及原始值的隐式类型转换》| html5jscss

评论关闭了.