zoukankan      html  css  js  c++  java
  • JavaScript高级程序设计学习笔记 变量、数据类型

    1、变量

    ECMAScript 变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话来说,每个变量仅仅是一个用于保存值的占位符而已。定义变量要使用var操作符(注意var操作符是一个关键字),后跟变量名,如下所示:

    var message;

    这行代码定义了一个名为message的变量,该变量可以用来保存任何值(未经初始化的变量,会保存一个特殊的值—undefined).ECMAScript也支持直接初始化变量,因此在定义变量的同时就可以设置变量的值,如下所示:

    var message = "hi";

    在此,变量message中保存了一个字符串"hi"。像这样初始化变量并不会把它标记为字符串类型;初始化的过程就是给变量赋值这么简单。因此,可以在修改变量值的同时修改值的类型,如下所示:

    var message = "hi";
    message = 100;            //有效,但不推荐

    有一点必须注意,即使用var操作符定义的变量将成为该变量的作用域中的局部变量。也就是说,如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁,例如:

    function test(){
    var message = "hi";    //局部变量
    }
    test();
    alert(message);    //undefined

     这里,变量message是在函数中用var定义的。当函数被调用时,就会创建该变量并未其赋值。而在此后,这个变量又会立即被销毁,因此例子中的下一行代码就会导致报错。不过,可以像下面这样省略var操作符,从而创建一个全局变量:

    function test() {
        message = "hi";    //全局变量    
    }
    test();
    alert(message);     //"hi"

    这个例子省略了var操作符,因而message就成了全局变量。这样,只要调用过一次test()函数,这个变量就有了定义,就可以在函数外部的任何地方被访问到。

    虽然省略var操作符可以定义全局变量,但这也不是我们推荐的做法。因为在局部作用域中定义的全局变量很难维护,而且如果有意地忽略了var操作符,也会由于相应变量不会马上就有定义而导致不必要的混乱。

    可以使用一条语句定义多个变量,只要像下面这样把每个变量(初始化不初始化均可)用逗号分隔开即可。

    var message = "hi",
        found = false,
        age = 29

    这个例子定义并初始化了3个变量。同样由于ECMAScript是松散类型的,因而使用不同类型初始化变量的操作可以放在同一条语句中来完成。虽然代码里换行和变量缩进不是必需的,但这样做可以提高可读性。

    2、数据类型

    ECMAScript中有5种简单数据类型(也称为基本数据类型):Undefind、Null、Boolean、Number和String。还有一种复杂数据类型—Object,Object本质上是由一组无序的名值对组成的。ECMAScript不支持任何创建自定义类型的机制,而所有值最终都是上述6种数据类型之一。

    2.1 typeof操作符

    鉴于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型—typeof就是负责提供这方面信息的操作符。对一个值使用typeof操作符可能返回下列某个字符串:

    "undefined" — 如果这个值未定义;

    "boolean" — 如果这个值是布尔值;

    "string" — 如果这个值是字符串;

    "number" — 如果这个值是数值;

    "object" — 如果这个值是对象或null;

    "function" — 如果这个值是函数。

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

    var message = "some string";
    alert (typeof message);    // “string”
    alert (typeof (message));   //"string"
    alert(typeof 95);          //"number"

    这几个例子说明,typeof操作符的操作数可以是变量,也可以是数值字面量。注意,typeof是一个操作符而不是函数,因此圆括号是不必需的(尽管也可以使用)。

    从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。

    2.2 Undefined类型

    Udefined类型只有一个值,即特殊的undefined。在使用var变量但未对其加以初始化时,这个变量的值就是undefined。

    var message;
    alert(massage == undefined);    //true

    不过包含undefined的变量与尚未定义的变量还是不一样的。看看下面这个例子。

    var message;
    alert(message);     // "undefined"
    alert(age);    //产生错误

    对于尚未声明过的变量,只能执行一项操作,即使用typeof操作符检测其数据类型。

    var message;
    alert(typeof message);    // “undefined”
    alert(typeof age);           // "undefined"

    结果表明,对未初始化和未声明的变量执行typeof操作符都返回了undefined值;这个结果有其逻辑上的合理性。因为虽然这两种变量从技术角度看有本质区别,但实际上无论对哪种变量也不可能执行真正的操作。
    即便未初始化的变量会自动被赋予undefined的值,但我们仍然建议读者养成显示初始化变量(即在声明变量的同时给变量赋值)的习惯。如果能够做到这一点,那么当typeof操作符返回undefined值时,我们就知道被检测的变量是还没有被声明的,而不是尚未初始化的了。

    2.3 Null类型

    Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null值时会返回"object"的原因,如下图例子所示:

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

    如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值。 这样一来,只要检查null值就可以知道相应的变量是否已经保存了一个对象的引用了,如下面的例子所示:

    if (typeof car != null){
        //对car对象执行某些操作
    }

    实际上,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true;

    alert(null == undefined);     //true

    2.4 Boolean

    Boolean类型是ECMAScript中使用的最多的一种类型,该类型只有两个字面值:true和false。 这两个值与数字值不是一回事,因此true不一定等于1,而false也不一定等于0;

    虽然Boolean类型的字面值只有两个,但ECMAScript中所有类型的值都有与这两个Boolean值等价的值。 要将一个值转换为其对应的Boolean值,可以调用转型函数Boolean()。可以对任何数据类型的值调用Boolean()函数,而且总会返回一个Boolean值。下表给出了各种数据类型及其对应的转换规则。

    数据类型  转换为true的值 转换为false的值
    Boolen true false
    String 任何非空字符串 ""(空字符串)
    Number 任何非零数字值(包括无穷大) 0和NaN
    Object 任何对象 null
    Undefined n/a(不适用) undefined

    2.5 Number类型

    Number类型应该是ECMAScript中最令人关注的数据类型了,这种类型使用IEEE754格式来表示整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)。为支持各种数值类型,ECMA-262定义了各种不同的数值字面量格式。

    最基本的数值字面量格式是十进制整数,十进制整数可以像下面这样直接在代码中输入:

    var intNum = 55;      //整数

    除了十进制表示,整数还可以通过八进制或十六进制的字面值表示。 其中八进制字面值的第一位必须是零(0),然后是八进制数字序列(0~7)。如果字面值中的数值超出了范围,那么前导零将被忽略,后面的数值将被当做十进制数值解析。请看下面的例子:

    var octalNum1 = 070;       // 八进制的56
    var octalNum2 = 079;       //无效的八进制数值,解析为79
    var octalNum3 = 08;        //无效的八进制数值,解析为8

    十六进制字面值的前两位必须为0x,后跟任何十六进制数字(0~9及A~F)。其中字母A~F可以大写,也可以小写。如下面的例子所示:

    var hexNum1 = 0xA;            //十六进制的10
    var hexNum2 = 0x1f;           //十六进制的31

    虽然数值可以用八进制或者十六进制表示,但在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换为十进制数值。

    1、浮点数值

    所谓浮点数值,就是该数值中必须包含一个小数点,并且小数点后面至少必须有一位数字。虽然小数点前面可以没有整数,但我们不推荐这种写法。

    由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数值转换为整数值。如果小数点后面没有任何数字,那么这个数值就可以作为整数值来保存。同样地,如果浮点数值本身表示的就是一个整数(如1.0),那么该值也会被转换为整数。

    对于那些极大或者极小的数值,可以用e表示法(即科学计数法)来表示浮点数值。 用e表示法表示的数值等于e前面的数值乘以10的指数次幂。如:

    var floatNum1 = 3.125e7;    //表示等于31250000
    var floatNum2 = 3e-17;      //表示等于0.00000000000000003

    在默认情况下,ECMAScript都会将那些小数点后面带有6个零以上的浮点数值转换为以e表示法表示的数值。

    浮点数值的最高精确度是17位小数,但在进行算术计算时其精确度远远不如整数。例如,0.1加上0.2的结果不是0.3,而是0.30000000000000004.这个小小的误差会导致无法测试特点的浮点数值。因此,永远不要测试某个特定的浮点数值。

    2、数值范围

    ECMAScript能够表示的最小数值保存在Number.MIN_VALUE中,在大多数浏览器中,这个值是5e-324;能够表示的最大数值保存在Number.MAX_VALUE中,在大多数浏览器中,这个值是1.7976931348623157e+308。如果某次计算结果得到了一个超出JavaScript数值范围的值,如果这个这个数是负数,则自动转换为特殊的-Infinity(负无穷),如果这个数值是正数,则会被转换为Infinity(正无穷)。

    如果某次计算返回了正或负的Infinity值,那么该值将无法继续参与下一次的计算。要想确定一个数是不是有穷的,可以使用IsFinite()函数。这个函数在参数为最小与最大之间时会返回true;

    3、NaN

    NaN,即非数值(not a number)是一个特殊的值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会是抛出错误了)。例如,自其它编程语言中,任何数值除以0都会导致错误,从而停止代码执行。但在ECMAScript中,任何数值除以0都会返回NaN,因此不会影响其他代码的执行。

    NaN有两个特点。 首先,任何涉及NaN的操作都会返回NaN,这个特点在多不计算中有可能导致问题。其次,NaN与任何至都不相等,包括Nan本身。

    isNaN()函数接受一个参数,该参数可以是任何类型,而函数会帮我们确定这个参数是否“不是数值”。 isNaN()接到一个值之后,会尝试将这个值转换为数值,某些不是数值的值会直接转换为数值,而任何无法转换为数值的值都会导致这个函数返回true。

    alert(isNaN(NaN));          //true
    alert(isNaN(10));            //false
    alert(isNaN("10"));         //false
    alert(isNaN("blue"));       //true(不能被转换为数值)
    alert(isNaN(true));          //false(可以被转换为数值1)

    4、数值转换

    Number() 、parseInt()、parseFloat() 前者可以用于任何数据类型,后两个则专门把字符串转换成数值。

    Number()

    Boolean值,true和false分布转换为1和0;

    数字值,只是简单的传入和返回;

    如果是null值,返回0;

    如果是undefined,返回NaN;

    如果是字符串,遵循以下规则:

    如果只包含数字,则转换为十进制数值。("011"也会变成11,忽略前导零);如果字符串中含有有效的浮点格式,则将其转换为相同大小的浮点数值。(忽略前导零,"10.3"转换为10.3,"10.3nn"返回NaN); 如果字符串含有有效的十六进制格式,如"0xf",则转换为相同大小的十进制整数值; 如果字符串是空的(不包含任何字符串如""),则将转为为0;如果字符串包含上述格式之外的字符,则将其转换为NaN。

    如果是对象,则调用对象的valueof()方法,然后依照前面的规则转换返回值。如果转换的结果是NaN,则调用对象的toString()方法,再一次按照前面的规则转换返回的字符串。

    由于Number()函数在转换字符串时比较复杂且不够合理,因此在处理整数的时候更常用的是parseInt()函数。parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。它会忽略字符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者正负号,parseInt()会返回NaN。也就是说用parseInt()转换空字符串会返回NaN(用Number()会返回0)。如果遇到第一个非空字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。例如,"1234blue"会转换为1234.类似地,"22.5"会转换为22,因为小数点并不是有效的数字字符。如果字符串的第一个字符是数字字符,parseInt()也能识别出各种整数格式(十进制、八进制和十六进制)。下面给出一些例子:

    var num1 = parseInt("1234blue");    //1234
    var num2 = parseInt(" ");           //NaN
    var num3 = parseInt("0xA");      //10(十六进制)
    var num4 = parseInt("22.5");     //22
    var num5 = parseInt("070");    //56(八进制)
    var num6 = parseInt("70");     //70
    var num7 = parseInt("0xf");     //15(十六进制)

    parseInt()可以指定第二参数:转换时使用的基数(即多少进制)。

    var num = parseInt("0xAF",16);   //175
    var num1 = parseInt("AF",16);      //175
    var num2 = parseInt("AF",16);   //NaN
  • 相关阅读:
    Matplotlib 绘图库 基本使用方法
    linux socat命令
    linux shell重定向
    linux man命令
    bashttpd使用手册
    libcurl代码示例
    vim文件头部注释配置
    linux join命令
    iterm2切换显示屏vim乱行解决
    分形与混沌
  • 原文地址:https://www.cnblogs.com/blackwood/p/2788577.html
Copyright © 2011-2022 走看看