js数据类型必须得知道的那些事

作者: 诺克斯1 | 来源:发表于2019-07-24 16:41 被阅读0次

    记得刚学习js的时候,在变量的赋值上经常会出现一些自认为是莫名奇妙的bug,自己找了半天也找不出问题~
    当然js的数据类型转化也是让我头疼不已~ 明明上一秒还是小明,下一秒就变成了小红,经常是让人摸不着头脑.最为一个有自知之明的前端小菜鸟,还是有必要花时间来整理一下这些知识点的 ,把关于数据类型的知识点给整理了一下~做个小小的分享

    以下是本文的提纲

    数据类型

    基本类型

    引用类型

    不同数据类型的赋值区别

    不同数据类型作为参数传递的区别

    数据类型隐式转化

    基本运算

    1.字符串与数组相比

    2.==与 = ==

    3.布尔类型与其他类型

    4.null和undefined

    5.引用类型运算

    数据类型判断

    typeof

    Object.prototype.toString.call()

    到底什么是数据类型?

    就是计算机里面有各种数据值,不同的数据值的处理方式和储蓄方式都不同,我们为这些值分好了类别,统称为 数据类型

    通俗点来说,就是计算机也需要对人说人话,对鬼说鬼话~

    但是...现实中总是那么残酷,来看几段代码先

     //数据类型间的赋值
     var a =1 ;
     var b =a ;
     function num (c){
      c = 999;
     }
     num(a);
     console.log(a)//1
     console.log(b)//1
     console.log(c)//999
     ​
      var obj = {
      a:1
     }
     var obj2 = obj;
     console.log(obj2); //1
     ​
     obj2.a= 10;
     console.log(obj)
     ------------------------------------------------------
     console.log(1 + 'abc') /1abc
     ​
     var obj = {
      width: '100'
     };
     ​
     obj.width + 20 // "10020"
     ----------------------------------------------------
     ​
     var a = [1,2];
     ​
     var b = [3,4];
     ​
     console.log(a+b); //1,23,4
     ​
     ----------------------------------------------------------
     true + 0 // 1</pre>
    
    • 那为什么会出现这样的情况呢,明明上一秒还是字符串,下一秒就变成了number

    • 数值与字符串相加,结果变成了字符串的拼接

    • 数组间的相加虽然不常见,但是结果也是让人匪夷所思

    为了弄清楚这些问题.我不得不查阅了大量资料,以及做一些必要的测试来搞懂他,首先还是要对js中的数据类型要有个大致的了解~

    js中的数据类型总共分为2个大类, 基本类型,对象类型,也可以叫做值类型和引用类型

    先来看看基本类型,常见的基本类型总共有5种

    js中提供了一种检测当前变量的数据类型的方法,也就是typeof关键字,我们先来试试看

    注意:[ typeof对于基本类型,除了 null 都可以显示正确的类型 ]

    Number

    String

    Boolean

    Undefined

    Null

    var a = 'abc';    
      var b = 1;
      var c =true;
      var d = undefined;
      var e = null;
     ​
      var f = [];
      var g = {};
     ​
      function h () {
      console.log(1)
      }
      console.log(typeof(a)) //string
      console.log(typeof(b)) //number
      console.log(typeof(c)) //boolean
      console.log(typeof(d)) //undefined
      console.log(typeof(e)) //object</pre>
    

    为什么null打印出来是object呢 , 原因在于这是js的一个语言bug,null 本身是基本类型。

    原理是这样的,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“object”。

    引用类型:

    • 数组

    • function

    • Obj

     var f = [];    
     var g = {};
     ​
     function h () {
      console.log(1)
     }    
     ​
     console.log(typeof(f)) //object
     console.log(typeof(g)) //object
     console.log(typeof(h)) //object</pre>
    

    在这里其实可以发现,typeof只可以检测基本的数据类型,而引用类型的检测不出具体的数据类型的,关于检测数据类型,我们在后面再看~

    基本类型和引用类型之间的区别

    我们先来看第一个问题:把boj赋值一份给obj2,当改变了obj2中的属性值,obj的属性值也发生了改变,

    不同数据类型间赋值区别

    • 简单数据类型是存在内存中的栈中的,而引用类型的数据是存在内存中的堆中的,但是变量的声明都是在栈上

    • 赋值只是把栈中的内存地址给另外一个变量,基本数据类型就等于把值复制给了另一个,引用类型就等于把我的内存地址赋值给另外一个变量,而他们都指向同一个堆中的数据

    • 而引用类型数据存储在堆中,栈中的地址指向堆,obj1改变堆中的数据,obj又跟她指向同一个.

     //数据类型间的赋值
     var a =1 ;
     var b =a ;
     console.log(a)//1
     console.log(b)//1
     ​
     ​
      var obj = {
      a:1
     }
     var obj1 = obj;
     console.log(obj2); //1
     ​
     obj1.a= 10;
     console.log(obj)</pre>
    
    image.png

    一张图简单的来理解

    不同数据类型间传参区别

    var a =1 ;
     function num (c){
      c = 999;
     }
     num(a);
     console.log(c)//999
     ​
     ​
     var obj = {
      a:10
     }
     ​
     function changen(obj1){
      obj1.a=30;
     }
     changen(obj);
     console.log(obj.a) //30</pre>
    
    image.png

    数据类型隐式转化

    • 字符串和数字比较,字符串会被转换数字

    • 布尔值和其他类型比较,会被转换成数字

    运算符

    基本数据类型

    我们发现,js在对不同数据类型做运算的时候,会把不同类型的变量进行转变,比如 1 + '1' = ‘11’,简单数据类型的隐式转化常见的有以下几种

    • 字符串加数字,数字就会转成字符串(上面已经写了)

    • 数字减字符串,字符串转成数字 (1 - '1' //0)

    console.log(1-'1')  // 0
    
    • 如果字符串不是纯数字就会转成NaN。字符串减数字也一样, 乘,除,大于,小于跟减的转换也是一样。
    console.log(1-'1a') //NAN</pre>
    

    ==与===

    == 允许在相等比较中进行强制类型转换,而== = 不允许,如果两个值的类型不同,我们就需要考虑有没有强制类型转换的必要,有就用= =,没有就用===,不用在乎性能。

     //字符串和数字之间的相等比较,将字符串转换为数字再进行比较
     var a =1;;
     var b ='1';
     a==b //true
     a===b //false</pre>
    

    其他类型与布尔类型相比

    //先将布尔类型转为数字
     true //1
     false //0
     var a = true;
     var b = '999';
     a == b //false</pre>
    

    null和undefined比较

    console.log(null == undefined) //trun
    console.log(null === undefined) //false</pre>
    

    引用类型

    var a = [1,2];
     var b = [3,4];
     console.log(a+b); //1,23,4</pre>
    

    要解决这个疑问,先要了解以下es5的规范

    ES5 规范11.6.1 节,如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+ 将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用ToPrimitive 抽象操作(规范9.1 节),该抽象操作再调用[[DefaultValue]](规范8.12.8节),以数字作为上下文

    如果加其中的一个操作数是字符串(或者通过此规范能得到字符串),则进行字符串拼接,否则执行数字加法

    ToPrimitive会做以下3件事:

    1.先计算obj.valueOf(),,如果结果为原始值,则返回此结果 (obj值的是引用的数据类型)

    2.否则.计算obj.toString(),如果结果是原始值,则返回此结果

    3.否则,抛出异常

     var arr = [1,2];
     console.log(arr.valueOf()); // [1,2]
     console.log(arr.toString()); // 1,2</pre>
    

    数据类型检测

    typeof(检查基本数据类型)

    typeof对于基本数据类型判断是没有问题的,但是遇到引用数据类型(如:Array,obj,function)是不起作用的,输出的都是object,那个这个时候检查引用数据类型就要用到下面这个方法了

     var f = [];    
     var g = {};
     ​
     function h () {
      console.log(1)
     }    
     ​
     console.log(typeof(f)) //object
     console.log(typeof(g)) //object
     console.log(typeof(h)) //object</pre>
    

    Object.prototype.toString.call() (检查引用数据类型)

     var f = [];
     var g = {};
     function h () {
      console.log(1)
     }
     console.log(Object.prototype.toString.call(f)); //[object Array]
     console.log(Object.prototype.toString.call(g)); //[object Object]
     console.log(Object.prototype.toString.call(h)); //[object Function]</pre>
    

    相关文章

      网友评论

        本文标题:js数据类型必须得知道的那些事

        本文链接:https://www.haomeiwen.com/subject/cvxfrctx.html