module1-01-JS数据类型

JS的数据类型---代码基本测试功能(上)

  • 虽然现在前端技术很多很复杂,但是归根到底,学好js才是重中之重,只有扎实的基础才能往上面盖大楼。

  • 为什么学习这个是必要的呢,首先可以在边界数据类型条件判断问题中体现出来

    • 比如一个函数检测参数类型当中

  • 接下来围绕概念检测方法转换方法进行讲解

一、数据类型的基本概念

  • 下面用一张图来说明

  • 其中基础数据类型为7中

    • undefined、Null、Boolean、String、Number、Symbol、BigInt

  • 复杂数据类型为object,且包括其之下的类型

1.1 存储方式

  • ① 基础类型存储在栈内存,被引用或拷贝,会创建一个完全相等的变量

  • ② 引用类型存储在堆内存,存储的是地址,其变量名存储在栈中,多个引用指向桐一个地址,这里会涉及一个“共享的概念”

1.2 题目理解

  • 用题目来讲解一下共享的概念

  • ① 初出茅庐

    • let a = {
         name: 'lee',
         age: 18
      }
      let b = a;
      console.log(a.name); // lee
      b.name = 'son'
      console.log(a.name); // son
      console.log(b.name); // son
    • 这里面通过b的改动使a的值也产生了变化,足够说明共享这个概念

  • ② 渐入佳境

    • let a = {
         name: 'Julia',
         age: 20
      }
      function change(o) {
         o.age = 24
         o = {
             name: 'Kath',
             age: 30
        }
         return o;
      }

      let b = change(a);
      console.log(b.age); // 这里面b的值是change函数return的o, 所以是30
      console.log(a.age); // 这里不像上面那题那样也改变了, 而是为24
    • 函数传参进来的只是一个内存地址, 在函数里面改变参数的地址指向不会影响实参的地址指向

二、数据类型的判断方法

  • 也就是数据类型的检测方法

  • 其中判断方法有很多种

    • ① typeof

    • ② instanceof

    • ③ Object.toString.call()

2.1 typeof

  • 其中null检测出object可以说是js的一个bug

    • 可以用 === 判断是否为null

  • 复杂数据类型中,除了function,其他都是无法直接使用typeof判断出来的

2.2 instanceof

  • 返回一个布尔值,表示是否属于该原型对象

  • 其中基本数据类型要用new出来的实例对象才能判断,不然为false

  • 自己实现一个instanceof

function myInstanceof(left, right) {
   if (typeof left !== object || left === null) return false;
   let proto = Object.getPrototypeOf(left);
   while(true) {
       if (proto === null) return false;
       if (proto === right.prototype) return true; // 比较right的原型对象
       proto = Object.getPrototypeOf(proto); // 如果还没有结束循环则继续往下判断
  }
}
  • getPrototypeOf是Object对象自带的API,能拿到参数的原型对象

2.3 判断以上两种方法的差异

  • ① instanceof可以准确地判断复杂引用类型,但是不能正确判断基础数据类型

  • ② typeof虽然可以判断基础数据类型,但是除了function之外其他的复杂数据类型无法判断

2.4 Object.prototype.toString.call**

  • 要注意返回的都是[object Xxx]的格式,其中第一个X是大写

  • 自行封装的一个getType

  • 这里要注意的是,typeof无法识别出new 基础类型的数据类型,比如new String('a'),会让最后的返回结果为String而不是string,所以可以针对大小写进行转换

三、数据类型的转换方式

  • 接下来用一张图片来开启这个内容

3.1 强制类型转换

  • Number()、parseInt()、parseFloat()、toString()、String()、Boolean()

  • 如这样的话会强制进行数据类型的转换

  • ① Number

  • 接下来展示一些Number转换之后的结果

  • ② Boolean

    • 除了undefined、null、false、0(包括-0跟+0)、‘’、NaN转换出来的是false。其他都是true

    • 比如

    • Boolean(0)          //false
      Boolean(null)       //false
      Boolean(undefined)  //false
      Boolean(NaN)        //false
      Boolean(1)          //true
      Boolean(13)         //true
      Boolean('12')       //true

3.2 隐式类型转换

  • 如遇到以下 符号 / 关键字 都会触发隐式转换

  • 接下来主要说==和+这两个符号触发的隐式转换

  • ① ==

    • 如果类型相同,则不用进行转换

    • 如果其中一个操作值是null或undefined,则另一方必须是null或者undefined才会返回true

      • undefined == null // true

      • undefined == undefined // true

      • null == null // true

    • 如果其中一方是Symbol,则返回false

    • 如果两个操作符是number和string,则转换为number

    • 如果其中一个是boolean,则转换成number

    • 如果一个操作之为object,且另一方为string、nukber、symbol,则把object转换为原始数据类型再判断(valueOf、toString)

      比如以下结果

      null == undefined       // true  规则2
      null == 0               // false 规则2
      '' == null              // false 规则2
      '' == 0                 // true 规则4 字符串转隐式转换成Number之后再对比
      '123' == 123            // true 规则4 字符串转隐式转换成Number之后再对比
      0 == false              // true e规则 布尔型隐式转换成Number之后再对比
      1 == true               // true e规则 布尔型隐式转换成Number之后再对比
      var a = {
        value: 0,
        valueOf: function() {
          this.value++;
          return this.value;
        }
      };
      // 注意这里a又可以等于1、2、3
      console.log(a == 1 && a == 2 && a ==3);  //true f规则 Object隐式转换
      // 注:但是执行过3遍之后,再重新执行a==3或之前的数字就是false,因为value已经加上去了,这里需要注意一下
  • ② +

    • 如果其中一个是字符串,另外一个是undefined、null、Boolean则调用toString()进行字符串拼接

      • 如果是纯对象、数组、正则,则默认调用转换方法再拼接

    • 如果其中一个是Numebr,另外一个是undefined、null、Boolean或Number,则调用Number()并进行加法运算,对象、数组、正则跟上一样

    • 如果其中一个是字符串、一个是数字则按照字符串拼接规则

      比如以下结果

      1 + 2        // 3  常规情况
      '1' + '2'    // '12' 常规情况
      // 下面看一下特殊情况
      '1' + undefined   // "1undefined" 规则1,undefined转换字符串
      '1' + null        // "1null" 规则1,null转换字符串
      '1' + true        // "1true" 规则1,true转换字符串
      '1' + 1n          // '11' 比较特殊字符串和BigInt相加,BigInt转换为字符串
      1 + undefined     // NaN 规则2,undefined转换数字相加NaN
      1 + null          // 1   规则2,null转换为0
      1 + true          // 2   规则2,true转换为1,二者相加为2
      1 + 1n            // 错误 不能把BigInt和Number类型直接混合相加
      '1' + 3           // '13' 规则3,字符串拼接
      • 注意undefined转换为数字是NaN

3.3 对象转换规则

  • ① 如果部署了[Symbol.toPrimitive]()方法则优先调用再返回

  • ② 调用valueOf(),如果转换为基础类型则返回

  • ③ 调用toString(),如果转换为基础类型则返回

  • ④ 如果都没有返回基础类型,则报错

    比如以下代码

    var obj = {
     value: 1,
     valueOf() {
       return 2;
    },
     toString() {
       return '3'
    },
    [Symbol.toPrimitive]() {
       return 4
    }
    }
    console.log(obj + 1); // 输出5
    // 因为有Symbol.toPrimitive,就优先执行这个;如果Symbol.toPrimitive这段代码删掉,则执行valueOf打印结果为3;如果valueOf也去掉,则调用toString返回'31'(字符串拼接)
    // 再看两个特殊的case:
    10 + {}
    // "10[object Object]",注意:{}会默认调用valueOf是{},不是基础类型继续转换,调用toString,返回结果"[object Object]",于是和10进行'+'运算,按照字符串拼接规则来,参考'+'的规则C
    [1,2,undefined,4,5] + 10
    // "1,2,,4,510",注意[1,2,undefined,4,5]会默认先调用valueOf结果还是这个数组,不是基础数据类型继续转换,也还是调用toString,返回"1,2,,4,5",然后再和10进行运算,还是按照字符串拼接规则,参考'+'的第3条规则
posted @ 2021-02-20 18:43  叻仔猪  阅读(124)  评论(0编辑  收藏  举报