TypeScript实战
上QQ阅读APP看书,第一时间看更新

2.7 数字

数字是一种用来表示数的书写符号。不同的记数系统可以使用相同的数字。数字在复数范围内可以分实数和虚数,实数又可以划分有理数和无理数或分为整数和小数,任何有理数都可以化成分数形式。

一般在现实生活中,常用的数字进制是十进制,计算机内部是基于二进制的。不同进制的数可以相互换算。数学之美,可以用数字来抽象现实的事物发展规律,从而指导现实生活,为人类服务。

在一个应用程序中,数字和字符串一样,是非常常用的一种数据类型,在一些财务或工程领域的软件中更显重要。

在TypeScript中,可以用number来定义一个数值类型的变量。另外,可以利用number的类型封装对象Number,调用其构造函数来创建一个Number对象,它的值是number类型的,如代码2-72所示。

【代码2-72】 Number基本用法示例:Number.ts

    01  let a: number = 2.8;
    02  //'number' is a primitive, but 'Number' is a wrapper object
    03  //let b: number = new Number("2");     //错误
    04  let c: Number = new Number("2");
    05  alert(c);      //2
    06  let d: Number = new Number(3);
    07  alert(d);      //3
    08  let e: Number = new Number(true);
    09  alert(e);      //1
    10  let f: Number = new Number(false);
    11  alert(f);      //0
    12  let g: Number = new Number("true");
    13  alert(g);      //NaN
    14  let h: Number = new Number({});
    15  alert(h);      //NaN
    16  let m: Number = new Number(6);
    17  alert(m);      //6

可以用let或者var进行数值变量的声明。在代码2-72中,01行中用let声明了一个数值变量a,并初始化其值为2.8。04行用new Number("2")构造函数来创建值为2的Number对象。16行用new Number(6)构造函数也可以创建值为6的Number对象。new Number(true)和Number(false)分别返回值为1和0的Number对象。

提示

传入的参数将在Number构造函数中被转换到number,如果转换失败,就返回NaN,否则返回转换的值为number类型的Number对象。

2.7.1 Number的属性

数值作为一个常用的对象,其中也有一些常用的属性来说明对象的相关信息。例如,数值本身是有最大值和最小值的。表2.7列出了一组Number对象的属性。

表2.7 Number基本属性

下面用代码来输出Number对象的属性。代码2-73给出了Number属性中的基本用法。

【代码2-73】 Number属性示例:Number2.ts

    01  console.log("number最大值:" + Number.MAX_VALUE);
    02  console.log("number最小值:" + Number.MIN_VALUE);
    03  console.log("负无穷: " + Number.NEGATIVE_INFINITY);
    04  console.log("正无穷: " + Number.POSITIVE_INFINITY);
    05  console.log(Number.prototype);

2.7.2 NaN

NaN是代表非数字值的特殊值,用于指示某个值不是数字。可以把Number对象设置为该值,来指示其不是数字值。可以使用isNaN()全局函数来判断一个值是否是NaN值。

Number.NaN是一个特殊值,说明某些算术运算(如求负数的平方根)的结果不是数字。方法parseInt()和parseFloat()在不能解析指定的字符串时就返回这个值。

TypeScript以NaN的形式表示Number.NaN。注意,NaN与其他数值进行比较的结果总是不相等的,包括它自身在内。因此,不能与Number.NaN比较来检测一个值是不是数字,而只能调用isNaN()来比较,如代码2-74所示。

【代码2-74】 NaN示例:nan.ts

    01  let a = Number.NaN;
    02  let b = Number.NaN;
    03  console.log(a == b);      //false
    04  console.log(Number.isNaN(a));    //true

2.7.3 prototype

上面提到prototype属性使我们有能力向对象上动态添加属性和方法。在TypeScript中,函数可以直接用prototype对函数属性和方法进行扩展,如代码2-75所示。

【代码2-75】 prototype函数扩展示例:prototype_func.ts

    01  function people(id:string, name:string) {
    02     this.id = id;
    03     this.name = name;
    04  }
    05  var emp = new people("123", "Smith");
    06  var jack = new people("234", "JACK");
    07  people.prototype.email = "smith@163.com";
    08  people.prototype.walk = function () {
    09      console.log(this.name + " walk");
    10  }
    11  jack.email = "jack@163.com";
    12  console.log(emp.id);       // 123
    13  console.log(emp.name);     //Smith
    14  console.log(emp.email);         //smith@163.com
    15  console.log(emp.walk());   //Smith walk
    16  console.log(jack.id);      //234
    17  console.log(jack.email);        // jack@163.com
    18  console.log(jack.walk());       //jack walk

Number对象无法通过prototype直接添加属性和方法,如下所示。

    Number.prototype.prop2 = "3" ;//错误

那么该怎样去扩展Number对象呢?这里可以借助在Number接口interface上来进行扩展(接口将在后续章节详细说明),如代码2-76所示。

【代码2-76】 prototype对Number对象扩展示例:prototype_number.ts

    01  interface Number {
    02      padLeft(chars: string, length: number): string;
    03  }
    04  Number.prototype.padLeft = function (chars: string, length: number):
        string  {
    05      return (chars.repeat(length) + this);     //this代码值
    06  };
    07  let a = 9;
    08  console.log(a.padLeft("0", 3));          //0009

代码2-76中01~03行通过在interface Number接口上定义了一个padLeft的方法,可以在Number.prototype.padLeft上定义具体实现逻辑。

提示

TypeScript中的Number.prototype不能直接添加新的属性和方法,和JavaScript不一样。

2.7.4 Number的方法

Number对象不但包含一些属性,同时也包含一些方法。这些方法可以更好地为我们提供服务。表2.8列出了一组Number对象的基本方法。

表2.8 Number基本方法

下面针对Number的方法用代码来具体查看一下各方法的主要作用,这样更容易直观掌握各方法的实际含义,如代码2-77所示。

【代码2-77】 Number方法示例:method_number.ts

    01  let a = 12345.28;
    02  console.log(a.toExponential(2));         //1.23e+4
    03  console.log(a.toFixed(2));               //12345.28
    04  console.log(a.toLocaleString());         //12,345.28
    05  console.log(a.toString());               //12345.28
    06  console.log(a.toString(2));
    07  console.log(a.toString(8));              // 30071.2172702436561
    08  console.log(a.toPrecision(1));           //1e+4
    09  console.log(a.valueOf());                //12345.28
    10  console.log(Number.isFinite(a));         //true
    11  console.log(Number.isNaN(a));            //false
    12  console.log(Number.isInteger(a));        //false
    13  console.log(Number.isSafeInteger(a));    //false
    14  console.log(Number.parseFloat("2.18"));  //2.18
    15  console.log(Number.parseInt("2.18"));    //2
    16  console.log(Number.parseFloat("2.18"));  //2.18