JavaScript的基础数据类型进阶

JavaScript的几种基础数据类型进阶

JavaScriopt有几种基本类型?5种!Are you sure?
JavaScript常见的有五种基本类型:boolean,undefined,null,number,string。ES6新增了symbol,不常见的数据类型是bigInt。所以从严格意义上来说,目前JavaScript有七种基本数据类型。基本类型的判断使用typeof操作符,所有基础类型不可改变。

下面,我们来一探究竟这些数据类型与其转换规则吧!

  • Boolean类型

Boolean类型在实际的工作中被经常使用,当我们在处理某些JS的业务逻辑时,难免需要通过Boolean值来进行相关的判断,如if,三目运算等。

与Boolean类型相关的Boolean值转换方法是Boolean()函数。Boolean()的转换规则如下

Boolean(true);           // true
Boolean(false);          // false
Boolean(undefined);      // false
Boolean("");             // false
Boolean("  ");           // true
Booleam({});             // true
Booleam([]);             // true
Boolean(NaN);            // false

需要注意的是Boolean函数是if语句的隐式转换规则(括号内为非表达式):

var messeage = "    ";
if(messeage) {                           // 这里if语句进行了隐式转换,对message调用Boolean方法
    console.log(message);                // "    "
}

在使用逻辑非操作符时,这里有一个你可能不知道的骚操作:

!!true;           // true
!!false;          // false
!!undefined;      // false
!!"";             // false
!!"  ";           // true
!!{};             // true
!![];             // true
!!NaN;            // false
// 你发现了吗?

两个逻辑非操作转换成Boolean值的结果和Boolean()方法相同。

当然,可以通过new操作符对Boolean函数进行实例化,此时的Boolean为构造函数,可以传入一些参数。

  • Undefined类型

undefined表示当前的变量没有被赋值,它是全局对象的一个变量,不可修改,枚举,配置

var a;           
typeof a;             // undefined
typeof b;             // undefined,没有报错
a === "undefined";    // true,注意:这里是'==='
b === "undefined";    // Uncaught ReferenceError: b is not defined

通过typeof操作符能判断一个未声明或者已声明未赋值的变量是否是undefined。但是在实际中应该避免未声明变量的基本类型判断,因为它并不适合用于判断对象的属性是否存在。

或者细心的你会发现:

// 当JavaScript运行完某个函数时
function test() {
    var a = 100;
    console.log(a);
};
test();
// 打开浏览器控制台,你会看到以下输出
// 100
// undefined

所以,当函数没有明确的返回值(return nothing)的时候,它会默认返回一个undefined。

学到了吗?我们可以通过typeof判断某个变量是否未定义,或者你可以这样写:

var non;
// 常规的判断方法
if(typeof non === "undefined") { 
    // ... 
};
// 替代typeof的方法
if(non === void 0) { 
    // ... 
};
// 所以你会看到这样一个神奇的效果
undefined === void 0;      // true !!!

判断某个变量未定义,可以判断它是否等于void 0或者void(0),或许你已经在HTML中见识过它的强大了

<a herf="javascript: void(0)">这是一个超链接</a>  <!-- 点击后不干任何事 -->

void 0代替undefined,可以避免undefined被重写。

  • Null类型

首先,null不是一个属性,它是一个值(字面量),它也是一个指针,指向一个空对象的引用。

只有在我们主动将某个变量的值设置为null时,这个变量才能为null

var a = null;
a;                 // null

这里有一个需要注意的问题:

null == undefined;           // true,其实是 == 的隐式转换规则导致
null === undefined;          // false
  • Number类型

    Number是JavaScrit几种基本类型中最复杂难理解的类型,它包含的几种数值转换方法中总有一些让人费解的地方,虽然在实际的项目中可能并没有很大的意义,但还是需要将其理解透彻,以备不时之需,或者说在遇到问题时才能精准定位。

    Number包含两种数值类型:整数和浮点数(或许在其他强类型语言中,字符串有单双进度之分,但对于JS来说,它只表示双精度浮点数,记住了!)

    1. 无穷值Infinity

      在JavaScript中,数值有大小正负之分,所以无穷值也有正无穷+Infinity(Number.POSITIVE_INFINITY)和负无穷-Infinity(Number.NEGATIVE_INFINITY),ECMAscript中最小值保存在Number.MIN_VALUE中,如果某个值小于它,那这个值就是-Infinity,对应的最大值为Numner.MAX_VALUE

      Infinity的计算有些难以让人理解:

      Infinity + 1;               // Infinity;
      Infinity + Infinity;        // Infinity;
      Infinity - Infinity;        // NaN
      -Infinity + Infinity;       // NaN
      0 / 0;                      // NaN
      

      再看看下面这段取最大值的代码:

      let arr = [1,5,3,7,2];
      let maxVal = 0;
      arr.forEach(item => {
          if(item > maxVal) maxVal = item;
      })
      console.log(maxVal);                // 7
      // 这段代码有问题吗?
      

      如果我们不知道arr数组里面具体的数据(可能全部为负值),那么这段代码能拿到数组中的最大值吗?

      答案显然是拿不到,原因是maxVal = 0导致0始终是最大值,所以maxVal应该初始化为一个无限小的数值-Infinity:

      let maxVal = -Infinity;
      

      这就是Infinity的一个实际应用场景。

      判断一个数值是否是无穷可以使用isFinite(),ES6新增了Number.isFinite();

    2. 非数值NaN

      NaN是一个数值,通常表示一个计算错误时的返回值,看代码:

      typeof NaN;            // number
      Math.sqrt(-1);         // 尝试对一个负值求平方根,它将会返回NaN
      

      NaN虽然是一个数值,但是NaN的任何操作都会返回NaN

      NaN/0;                 // NaN
      NaN == NaN;            // false
      NaN === NaN;           // false
      NaN != NaN;            // true
      NaN !== NaN;           // true
      

      判断一个变量是否是数值可以使用isNaN(),ES6新增了Number.isNaN();

      a) isNaN()

      而在ES6之前,判断一个值是否是NaN的规则如下:

      判断参数是否是Number类型,如果是,则返回true;

      如果不是,调用Number()方法,将其转换为Number类型;

      然后判断转换后的值是否不恒等于(!==)它自己

      // isNaN的实现
      var isNaN = function(value) {
          var nan = Number(value);
          return nan !== nan;                     // 此处运用到了NaN !== NaN
      }
      

      所以,我们可以通过NaN的实现对一些难以理解的结果作出更好的解释:

      isNaN(NaN);             // true   Numer(NaN) == NaN;    NaN !== NaN;   true
      isNaN('red');           // true   Numer('red') == NaN;  NaN !== NaN;   true
      isNaN(true);            // false  Number(false) == 0;   0 !== 0;       false
      isNaN({});              // true   Number({}) == NaN;    ... ...
      isNaN([]);              // false  Number([]) == 0;      ... ...
      

      isNaN另一个强大的地方在于:可以通过它来确定某个值是否可以参与数学运算

      function isCompute(x) {
          if(isNaN(x)) console.log(x +  ' can not be computed!');
      }
      
      b) Number.isNaN()

      相比于isNaN()Number.isNaN()方法会将传入的参数转化成数值再判断,因为它更专注于number类型,其判断条件更为苛刻。实现如下

      var Number.isNaN = function(x) {
          return typeof x === 'number' && isNaN(x);
      };
      Numer.isNaN(NaN);               // true
      Number.isNaN(true);             // false
      Number.isNaN({});               // false
      Number.isNaN([]);               // false
      // 从直观的角度来看,[]不能表示为一个数值。
      

      NumberisNaN()的参数只接受数值,如果要让它返回true,这个数值必定为NaN。

    3. 数值转换

      Number类型的数值转换有三种:Number()、parseInt()和parseFloat()。

      a) Number()

      Number()函数的转换规则如下:

      类型
      true1
      false0
      null0
      undefinedNaN
      {}NaN
      []0
      ‘[]’NaN
      [2]2
      [2,1]NaN
      十六进制数十进制数
      其他非空对象对象的valueOf() 等于NaN ? 调用toString()
      b) parseInt()

      相比于Number()parseInt()是更为严格的转换形式,它是通过查找的方式找到数字,直到遇到第一个非空格字符,如果第一个字符不是数字或者负号,就会返回NaN。

      它可以接受第二个参数,表示转换的进制:当parseInt传入的第一个参数是字符串时,它会对字符串的每个字符挨个进行数值转换;当传入的第一个参数不是字符时,它会尝试将这个参数转化成十进制的字符串,然后再根据第二个参数对字符串按个转换。

      parseInt('1234a');                 // 1234
      parseInt('10', 8);                 // 8   8进制的10转换成10进制:1*8^1 + 0*8^0 = 8
      parseInt('0x10', 16);              // 16  16进制的0x10转化成10进制:12
      parseInt('0x10', 8);               // 0   8进制的0x10转化成10进制:x是8机制不能解析的字符
      parseInt(0x10, 8);                 /* 14  0x10为16进制,转换成10进制为16,所以相当于 parseInt('16', 8); */
      
      c) parseFloat()

      parseFloat只能解析十进制,他和parseInt大致相同,但是返回的是浮点数,这里就不再赘述。

  • String类型

    String类型表示由16个Unicode字符组成的元素,将其他类型的值转换成字符串主要有:toString()、String()。

    区别:

    toString()是一个属性方法,调用只能通过点语表示法调用,而且nullundefined没有这个方法,ES6新增:function.prototype.toString()toString()可以传入一个参数,表示输出的进制数;

    String()是一个构造函数,可以将null和undefined转换成对应的字符串。

    // 可以自己实现一个String方法并设置一些参数
    var String = function(value, hex){
        if(value === 'null') return 'null';
        else if(value === 'undefined') return 'undefined';
        else return  value.toString(hex);
    }
    
  • Symbol类型

    Symbol类型是ES6新增的基本数据类型,也可以将它成为atom(原子),它主要是用于设置对象的属性值,通过Symbol()构造函数可以给对象添加一个匿名属性(此时的键和值都是实例化的Symbol对象,且对象不可枚举)

    Symbol('a') !== Symbol('a');            // true
    var a = Symbol();
    typeof a ;                              // symbol
    let ob = {};
    obj[a] = ‘a’;
    JSON.stringfy(obj);                     // '{}'
    

    如需查看Symbol更详细的内容,请点击MDN Symbol

  • BigInt类型

    Number()类型中我们提到过:当某个计算后的数值大于Numbner.MAX_VALUE或小于Number.MIN_VALUE时,这个数就是对应的安全的无穷值,在ES规范中它用于表示另一种数据类型:大整数。

    const x = 2n ** 53n;
    tyopeof x === 'bigInt';       // true
    

JavaScript基础类型基本就这些了,内容如有不准确的地方,欢迎指正。

贵有恒何必三更眠五更起,最无益只怕一日曝十日寒。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值