专栏首页王金龙的专栏Javascript:Javascript数据类型详解

Javascript:Javascript数据类型详解

  要成为一个优秀的前端工程师,系统的学习Javascript,有夯实的Javascript基础,以及对语言本身的深刻的理解,是基本功。从Javascript数据类型开始,我将对Javascript知识体系进行系统的梳理。

  今天的主题是Javascript数据类型。

  ECMAScript中有5中简单的数据类型,也即基本数据类型:Undefined、Null、Boolean、Number和String。还有一种复杂数据类型:Object,Object本质上是由一组无序的名值对组成的。

  1、typeof操作符

  首先要介绍的是typeof操作符,因为ECMAScript是松散类型的,所以需要一种方式来检测给定变量的数据类型,就是typeof了。对一个值使用typeof操作符可能返回以下某个字符串。

  • "undefined"——如果这个值未定义,后面会详细说明
  • "boolean"——如果这个值是布尔值
  • "string"——如果这个值是字符串
  • "number"——如果这个值是数值
  • "object"——如果这个值是对象或者null
  • "function"——如果这个值是函数

  下面是几个使用typeof操作符的例子:

var typeText = "Javascript";
alert(typeof typeText);    //"string"
alert(typeof (typeText));    //"string"
alert(typeof 123);    //"number"

  一定注意,typeof是操作符,不是函数,所以上面第三行的代码中的括号,虽然可以使用,但不是必需的,加上括号反而会让人误解。

  2、Undefined类型

  这是第一个一定要详细说明的Javascript数据类型。Undefined类型只有一个值,也即undefined。

  在使用var声明变量但是未对其进行初始化的时候,这个变量的值就是undefined。例如:

var text;
alert(text == undefined);    //true

   这里声明了text变量,但是并未对其进行初始化,所以比较这个变量和undefined字面量,结果表明它们是相等的。其实上面的语句与下面的例子是等价的:

var text = undefined;
alert(text == undefined);    //true

但是,实际上我们并没有必要在声明变量的时候显式的将其初始化为undefined。

令人困惑的是,对未初始化的变量执行typeof操作,会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined值。

var text;    //这个变量声明后默认获得undefined值
//下面这个变量没有声明
//var message;

alert(typeof text);    //"undefined"
alert(typeof message);    //"undefined"

3、Null类型

  Null类型是要和undefined类型对比说明的。首先,Null类型也是只有一个值的数据类型。如其他语言一样,null只表示一个空对象指针,这也正是下面代码中用typeof才做服检测null值时会返回“object”的原因。如下所示:

var text = null;
alert(typeof text);    //"object"

  如果声明的一个变量明确的是要在将来保存一个对象,显式的将其初始化为null是一个好习惯,到时候只要直接检查该变量的值是不是null值就可以判定该变量是不是已经保存了一个对象的引用了。

  实际上,undefined值是派生自null值的,所以它们的相等行测试返回都是true:

alert(null == undefined);    //true 

  在介绍其他数据类型之前,我先比较这两个数据类型的深层次的不同点。

  学习了《Javascript高级程序设计》和阮一峰大神的博客之后,我对这两者的区别有了更深刻的认识:

null表示"没有对象",即该处不应该有值。典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。 (2) 作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype);    // null

  undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于undefined。 (2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。 (3)对象没有赋值的属性,该属性的值为undefined。 (4)函数没有返回值时,默认返回undefined。

var i;
i // undefined

function f(x){console.log(x)}
f() // undefined

var  o = new Object();
o.p // undefined

var x = f();
x // undefined

  4、Boolean类型

  Boolean类型只有两个字面值:true和false。这两个值是区分大小写的,并且这两个值与数字值1和0是两回事。

  虽然Boolean类型只有两个字面值,但是ECMAScript所有类型都可以转换为与Boolean中的这两个字面值等价的值,只需要调用Boolean()函数即可:

var val = "Hi";
var valAsBoolean = Boolean(val);

  所以,相应的,也就存在一个其他数据类型与Boolean字面值的对应关系,如下表所示:

数据类型

转换为true的值

转换为false的值

Boolean

true

false

String

任何非空字符串

""(空字符串)

Number

任何非零数字值(包含无穷大)

0和NaN

Object

任何对象

null

Undefined

不适用

undefined

  在程序运行的时候,比如在流控制语句中,识别程序自动执行相应的Boolean转换是很重要的,请看下例:

var text = "Hi";
if(text){
    alert(value is true);      
}

  上面代码在执行时,变量text就会被自动用Boolean()函数转换为Boolean类型。如果还要用String类型的text的话,那么就是一个重大错误了。所以一定要确切的知道在流控制语句中使用的是什么变量。

  5、Number类型

  Number类型使用IEEE754格式来表示整数和浮点数值。

  Javascript中最基本的数值字面值格式是十进制整数,除此之外整数还可以通过八进制(八进制字面值第一位为0,后面是0~7的八进制数字序列)、十六进制(前两位为0x,后跟任何十六位数字,0~9,及A~F)。在进行算术运算时,所有数值都将被转换成十进制数值进行计算。

  在Number类型中,我主要想说以下几个问题:

  1、永远不要测试某个特定的浮点数值,请看下例:

if(a + b == 0.3)        //不要做这样的测试
    alert("你得到了0.3!");

  如果这里a和b分别是0.05和0.25,或者是0.15和0.15都不会有问题,如果这两个值是0.1和0.2,那么测试就将无法通过。

  2、数值范围:

  最小值:Number.MIN_VALUE  =  5e-324  = -Infinity

  最大值:Number.MAX_VALUE  =  1.7976931348623157e+308  = Infinity

  如果在计算当中超过了最大或最小,都会被相应的转换为+Infinity或者-Infinity。

  当计算0/0时,会得到NaN,计算正数/0会得到Infinity,计算负数/0会得到-Infinity。

  3、NaN,即非数值,是一个特殊的值。这个数值用来表示一个本来要返回数值的操作数未返回数值的情况。

  NaN的特点:第一、任何涉及NaN的操作都会返回NaN。因为ECMAScript中任何数值除以非数值都会返回NaN,从而不会影响其他代码执行,所以这个特点在多步计算中可能会导致问题。其次、NaN与任何值都不想等,包括自身。

  针对这两个特点,ECMAScript定义了isNaN()函数,该函数接受一个任何类型的参数,函数会帮助我们确定这个参数是否是NaN。任何不能被转换成为数值的值都会导致这个函数返回true。请看下例:

alert(isNaN(NaN));    //true
alert(isNaN(10));    //false
alert(isNaN("true"));    //true

  4、数值转换

把非数值转换成数值的方法有Number()、paserInt()、parseFloat(),其中Number()可以接受任意类型的参数,paserInt()、parseFloat()则专门用于转换字符串。

     Number()类型的转换规则:

    (1)布尔值:true=1,false=0;

    (2)null=0;

    (3)undefined=NaN;

    (4)字符串:

         a: 字符串是数值,转换成十进制,忽略前导0,如果以“0x”开头,则按照十六进制解析成十进制(由此可见,八进制是个特殊的存在)

         b:字符串是空串,转换为0;

         c:除此之外全部转换成NaN;

    (5)对象:方法和isNaN()判断对象的方法基本相同。

alert(Number("hello world"));   // NaN
alert(Number("0011"));    //11

alert(Number("0x10"));   //16 
alert(Number(""));   //0 

  parseInt()函数是我们最常用的,它的转换规则:

   (1)忽略字符串前面的空格;

   (2)如果第一个字符不是数字字符或者正负号,返回NaN,空字符串同样返回NaN;

(3) 小数点在这个函数中被认为是非数值字符;

alert(parseInt(" "));  //NaN
alert(parseInt("       123"));   //123
alert(parseInt("123asjdllxcias"));   //123
alert(parseInt("asd"));  //NaN 

  同时,parseInt()还可以接受第二个参数作为第一个参数的基数,即告诉函数第一个参数该使用什么进制去解析。

alert(parseInt("12",8));   //10

alert(parseInt("12",16));   //18
alert(parseInt("1001",2));  // 9

  parseFloat()函数与parseInt()类似,区别在于parseFloat()函数会一直忽略前导0,并且不支持第二个参数,最后,如果小数点后全是0,则会返回整数。

  alert(parseFloat("0012.2"));   //12.2
  alert(parseFloat("0012.000000"));  //12
  alert(parseFloat("0012.2.33"));  //12.2   第二个小数点字符无效

  6、String类型

  String 对象用于处理文本(字符串)。

  创建 String 对象的语法:

  new String(s);
  String(s);
  参数 s 是要存储在 String 对象中或转换成原始字符串的值。

  当 String() 和运算符 new 一起作为构造函数使用时,它返回一个新创建的 String 对象,存放的是字符串 s 或 s 的字符串表示。

  当不用 new 运算符调用 String() 时,它只把 s 转换成原始的字符串,并返回转换后的值。

  字符串是 JavaScript 的一种基本的数据类型。

  String 对象的 length 属性声明了该字符串中的字符数。

  String 类定义了大量操作字符串的方法,例如从字符串中提取字符或子串,或者检索字符或子串。

  需要注意的是,JavaScript 的字符串是不可变的(immutable),String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串。

  在较早的 Netscape 代码基的 JavaScript 实现中(例如 Firefox 实现中),字符串的行为就像只读的字符数组。例如,从字符串 s 中提取第三个字符,可以用 s[2] 代替更加标准的 s.charAt(2)。此外,对字符串应用 for/in 循环时,它将枚举字符串中每个字符的数组下标(但要注意,ECMAScript 标准规定,不能枚举 length 属性)。因为字符串的数组行为不标准,所以应该避免使用它。

  7、Object类型

  Object类是所有JavaScript类的基类(父类),提供了一种创建自定义对象的简单方式,不再需要程序员定义构造函数。

  创建对象:

var o1 = new Object();   
var o2 = new Object;    //有效,但不推荐省略括号

  Object的每个实例都具有的属性和方法:

      • constructor:保存着用于创建当前对象的函数。对于前面的例子来说,构造函数就是Object();
      • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型链中)是否存在,其中作为参数的属性名必须以字符串的形式指定。
      • isPrototypeOf(Object):用于检查传入的对象是否是当前对象的原型。
      • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。
      • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
      • toString():返回对象的字符串表示。
      • valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法返回的值相同。

  作为ECMAScript中所有对象的基础,Object类型还有很多东西要说,今天就先说到这里,后面我将对Object进行更加深入的阐述。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java基础系列2:深入理解String类

    String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String。主要包括如下的五个内容:

    王金龙
  • 探究Java中的引用

    从JDK1.2版本开始,Java把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。本...

    王金龙
  • 前端实战Demo:一张图片搞定一页布局

          整个页面只有一个或者两个不多的需要操作的组件,比如按钮、输入框之类的,图片中的其他元素都只是作为静态展示的设计而存在,那么专门把这个几个元素抠...

    王金龙
  • 调用API弹出打印机属性对话框

    调用api弹出打印机属性对话框  Author:vitoriatang From:Internet .NET Framework封装了很多关于打印的对话框...

    Java架构师必看
  • Distribute Cached 使用

      在Kettle中说到Pentaho的MapReduce要用到它,就查了一下关于它的资料,以下是从官方查到的内容,记录一下。   DistributedCac...

    岑玉海
  • Mono 3.0.2 基于双工通信的WCF应用 Demo

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息。基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和...

    张善友
  • 海量数据面试题总结(2)-BitMap

    所谓BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来存储数据,因此可以大大节省存储空间。

    小萌哥
  • Dubbo 发布恢复维护后的第一个版本 2.5.4

    Dubbo 发布了恢复维护后的第一个版本 2.5.4,主要是解决 issues 和依赖升级。

    李鹏
  • WPF小坑第十七篇之自定义Window

    突然想到很早以前自定义的Window相关的东西,后来偷懒就直接用开源的MLib;这不今天又想到了她,然后再次尝试去摸索了摸索发现有意思的玩意,这不赶紧记录一下美...

    WPF程序员
  • Activity生命周期1

    Activity是Android组件中最基本也是最为常见用的四大组件之一,也是我们在开发过程之中接触最多的组件,所以了解Activity的生命周期,并正确的理...

    随心助手

扫码关注云+社区

领取腾讯云代金券