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