欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JS数据类型了解多少

程序员文章站 2022-04-09 23:11:09
...

 数据的运用多依赖于变量。变量:是用于存放数据的容器。其本质是程序在内存中申请的一块用来存放数据的空间。JS中,所有的变量都是保存在栈内存中的。

为什么需要数据类型?

 在计算机中,不同的数据所需占用的存储空间不同,为了充分利用存储空间,于是定义了不同的数据类型。而且,不同的数据类型,寓意也不同。

JavaScript 是一种「弱类型语言」,JS 的变量数据类型,是在程序运行的过程中,根据等号右边的值来确定的。

声明与定义

var x;//声明
var y=1;//定义

声明是起了变量名,给变量赋值则为定义,声明未赋值,默认补值undefined。

JS目前有七种通用的数据类型

  • 基本数据类型(值类型):String 字符串、Number 数值、Boolean 布尔值、Null 空值、Undefined 未定义。
  • 引用数据类型(引用类型):Object 对象。
  • ES6新增数据类型:Symbol 定义对象的唯一属性名(对这个属性暂时没太深入理解)

注意:内置对象 Function、Array、Date、RegExp、Error等都是属于 Object 类型。也就是说,除了那五种基本数据类型之外,其他的,都称之为 Object类型。

使用typeof(xx)检测xx的数据类型

数据类型之间最大的区别

  • 基本数据类型:参数赋值的时候,传数值(参数指向独立内存空间)。
    基本数据类型的值,直接保存在栈内存中。值与值之间是独立存在,修改一个变量不会影响其他的变量。
    var a = 23;
    var b = a;

    a++;

    console.log(a); // 打印结果:24
    console.log(b); // 打印结果:23
  • 引用数据类型:参数赋值的时候,传地址(参数指向同一片内存空间)。
    对象是保存到堆内存中的。每创建一个的对象,就会在堆内存中开辟出一个新的空间;而变量保存了对象的内存地址(对象的引用),保存在栈内存当中。如果两个变量保存了同一个对象的引用,当一个通过一个变量修改属性时,另一个也会受到影响。
    var obj1 = new Object();
    obj1.name = 'smyh';

    // 让 obj2 等于 obj1
    var obj2 = obj1;

    // 修改 obj1 的 name 属性
    obj1.name = 'vae';

    console.log(obj1.name); // 打印结果:vae
    console.log(obj2.name); // 打印结果:vae

数据类型内存模型图
注:变量名是有专门的表来维护的–变量表,此处说的是数据值保存的位置
JS数据类型了解多少
原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;

引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

延伸——垃圾回收站

它是专门释放对象内存的一个程序。

(1)在底层,后台伴随当前程序同时运行;引擎会定时自动调用垃圾回收期;
(2)总有一个对象不再被任何变量引用时,才释放。let obj=[]; obj=null;//释放一个引用

String

字符串里面的值不可被改变。虽然可以通过拼接等等实现貌似值的改变,但其实是指向的地址变了,内存中新开辟了一个内存空间。

新: ES6 模板字符串 反引号 `` ${}类似一个函数体,可以执行函数,获取数值,遍历等等

var name = 'xx';
var age = '26';

console.log('我是' + name + ',age:' + age); //传统写法

console.log(`我是${name},age:${age}`); //ES6 写法。注意语法格式

Number

在 JS 中,只要是数,就是 Number 数值型的。无论整浮、浮点数(即小数)、无论大小、无论正负,都是 Number 类型的。

数值范围

由于内存的限制,ECMAScript 并不能保存世界上所有的数值。

  • 最大值:Number.MAX_VALUE,这个值为: 1.7976931348623157e+308
  • 最小值:Number.MIN_VALUE,这个值为: 5e-324

如果使用 Number 表示的变量超过了最大值,则会返回Infinity。

  • 无穷大(正无穷):Infinity
  • 无穷小(负无穷):-Infinity

注意:typeof Infinity的返回结果是number。

NaN
NaN:是一个特殊的数字,表示Not a Number,非数值。
出现条件:无法转化为数字的数据使用了非+运算符号进行“运算“
检测方法:isNaN() console.log(isNaN('a')) //true

  • NaN 与任何值都不相等,包括 NaN 本身。
  • typeof NaN的返回结果是 number。
  • undefined做任何数值运算都是NaN
  • null做数值运算被视为0
console.log('a'-2) //NaN
console.log(typeof(NaN)) //number
console.log(isNaN('a')) //true
console.log(NaN==NaN)//false

连字符和加号的区别
如果加号两边都是 Number 类型,此时是数字相加。否则,就是连字符(用来连接字符串)。

console.log('2'+2-6) //16  ‘2’+2=‘22’ ‘22’-6->22-6=16(隐式转换)

浮点数的运算

运算精度问题
在JS中,整数的运算基本可以保证精确;但是小数的运算,可能会得到一个不精确的结果。所以,千万不要使用JS进行对精确度要求比较高的运算。

 var a = 0.1 + 0.2;
 console.log(a);  //打印结果:0.30000000000000004

这是因为,计算机在做运算时,所有的运算都要转换成二进制去计算。然而,有些数字转换成二进制之后,无法精确表示。比如说,0.1和0.2转换成二进制之后,是无穷的,因此存在浮点数的计算不精确的问题。
如果只是一些简单的精度问题,可以使用 toFix() 方法进行小数的截取。
市面上有很多针对数学运算的开源库,比如decimal.js、 Math.js。
Math.js:属于很全面的运算库,文件很大,压缩后的文件就有500kb。如果你的项目涉及到大型的复杂运算,可以使用 Math.js。
decimal.js:属于轻量的运算库,压缩后的文件只有32kb。大多数项目的数学运算,使用 decimal.js 足够了。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <script src="https://cdn.bootcdn.net/ajax/libs/decimal.js/10.2.0/decimal.min.js"></script>
        <script>
            console.log('加法:');
            var a = 0.1;
            var b = 0.2;
            console.log(a + b);
            console.log(new Decimal(a).add(new Decimal(b)).toNumber());

            console.log('减法:');
            var a = 1.0;
            var b = 0.7;
            console.log(a - b);
            console.log(new Decimal(a).sub(new Decimal(b)).toNumber());

            console.log('乘法:');
            var a = 1.01;
            var b = 1.003;
            console.log(a * b);
            console.log(new Decimal(a).mul(new Decimal(b)).toNumber());

            console.log('除法:');
            var a = 0.029;
            var b = 10;
            console.log(a / b);
            console.log(new Decimal(a).div(new Decimal(b)).toNumber());
        </script>
    </body>
</html>

Boolean

布尔型有两个值:true 和 false。布尔型和数字型相加时, true 按 1 来算 ,false 按 0 来算。

Null

  • Null 类型的值只有一个,就是 null。比如 let a = null。
  • 使用 typeof 检查一个 null 值时,会返回 object。
var myObj = null;
cosole.log(typeof myObj); // 打印结果:object

Undefined

  • Undefined 类型的值只有一个,就是 undefind。比如 let a = undefined。
  • 使用 typeof 检查一个 undefined 值时,会返回 undefined。

变量已声明,未赋值时 let x; console.log(x);
打印无返回值的函数function foo(){};console.log(foo())
typeof未声明的变量

console.log(typeof a)

not defined
未声明就调用了。

console.log( a+1)

null & undefined
undefined:定义未赋值 null:定义赋值空
空也相当于没有值,故 == true 但它们类型是不一样的 故=== false

console.log( null==undefined) //true
console.log( null===undefined) //false

有区别也有相似性
其中一个区别是,和数字运算时: undefined做任何数值运算都是NaN, null做数值运算被视为0

  • 10 + null 结果为 10。
  • 10 + undefined 结果为 NaN。

Object

ECMAScript中的对象其实就是一组数据和功能的集合。通过new操作符后跟要创建的对象类型的名称来创建。

var obj = new Object();

内置对象 Function、Array、Date、RegExp、Error等都是属于 Object 类型。也就是说,除了那五种基本数据类型之外,其他的,都称之为 Object类型。

JS中的类继承模式类似java中的基类和派生类的关系。派生类对象存储了基类的数据成员。

派生类的实例对象可以 访问基类的属性,方法。
JS中的内置对象Date、RegExp、Number、Function… 可以看做派生类、Object可以被看做 基类。
而特殊的是,javascript中Object这个基类,同时又是 Function这个派生类的 实例对象。

每个Object类型的实例共有的属性和方法:

  • constructor: 保存着用于创建当前对象的函数。
  • hasOwnProperty:用于检测给定的属性在当前对象的实例中是否存在。
  • isPrototypeOf : 用于检查传入的对象是否是当前对象的原型
  • propertyIsEnumerble : 用于检查给定属性能否使用for-in来枚举
  • toLocaleString() : 返回对象的字符串表示。
  • toString() : 返回对象的字符串表示。
  • valueOf() : 返回对象的字符串,数值,或布尔表示。通常和toString() 返回的值相同。

JS数据类型了解多少

Symbol

Symbol 类型的对象永远不相等,即便创建的时候传入相同的值。因此,可以用解决属性名冲突的问题(适用于多少编码),做为标记。
暂时了解不多:ES6学习☞Symbol

typeof & constructor

typeof
typeof 操作符来查看 JavaScript 变量的数据类型

typeof "John"                 // 返回 string
typeof 3.14                   // 返回 number
typeof NaN                    // 返回 number
typeof false                  // 返回 boolean
typeof [1,2,3,4]              // 返回 object
typeof {name:'John', age:34}  // 返回 object
typeof new Date()             // 返回 object
typeof function () {}         // 返回 function
typeof myCar                  // 返回 undefined (如果 myCar 没有声明)
typeof null                   // 返回 object

如果对象是 JavaScript Array 或 JavaScript Date ,我们就无法通过 typeof 来判断他们的类型,因为都是 返回 object。
constructor
constructor 属性返回所有 JavaScript 变量的构造函数。

console.log('free'.constructor)//[Function: String]
console.log((3.14).constructor)//[Function: Number]
console.log(false.constructor)//[Function: Boolean]
console.log([1,2].constructor)//[Function: Array]
console.log({name:'free',age:'24'}.constructor)//[Function: Object]
console.log(new Date().constructor)//[Function: Date]
console.log(function (){}.constructor)//[Function: Function]

巧妙利用toString(),检测对象的实际类型。

function isArray(myArray){ //巧妙检测数据类型
	return myArray.constructor.toString().indexOf('Array')>-1
}
console.log(isArray([1,2,3]))//true

类型转换

隐式转换和显示转换
通过 JavaScript 自身自动转换,通过使用 JavaScript 函数。

隐式类型: 部分算术运算符
显示转换:Number(),Boolean(),String(),parseInt()等

JS数据类型了解多少

相关标签: js