01.JS的数据类型

类型

js有八种基本数据类型:
1.Undefined
2.Null
3.Bollean
4.String
5.Number
6.Symbol
7.bigint
8.Object

一、Undefined、Null

Undefined 表示未定义,任何变量在未赋值前就是Undefined
Null 表示空,即定义了但是为空

值得注意的是,由于设计之初的问题,Undefined并未设计为关键字,也就是是Undefined会被重定义。
所有有时候我们会使用 void 0 来使用Undefined,void 0的返回值一定是Undefined

const Redefine = ()=>{
	Undefined = "hello word"
  und = void 0
  console.log(Undefined,und)
}
Redefine()
//输出结果为 hello word Undefined 

二、Bollean

Bollean 有两个值,true和false,即表示真假。

三、String

String即字符串,用于表示文本数据。最大长度为2的53次方-1,也被称为最大安全整数。

四、Number

Number表示数字,使用双精度浮点数规则。
还有几种其它情况:

  1. NaN 表示非数字
  2. infinity 无穷
  3. -infinity 负无穷大
  4. 0 +0 和-0 ,在加法中无所谓,除法中除于-0会得到无穷大
  5. 非整数不能用 == 或者 ===

如:0.1 + 0.2 !=0.3,因为计算机底层是用二进制,而我们js用双精度浮点数转换过程中存在精度丢失。
解决方法:先转化为整数再计算,使用最小精度值

Number.EPSILON 属性表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON)

五、Symbol

每个从 Symbol() 返回的 symbol 值都是唯一的,一个 symbol 值能作为对象属性的标识符,这是该数据类型仅有的目的。
它不能使用 new关键字来创建,直接Symbol()就可以使用
Symbol() 函数会返回 symbol 类型的值

我们很好理解,每个symbol返回值是唯一的,那能作为对象属性的标识符是什么意思呢?

var s="name";
var obj={
    s:"张三",
    [s]:'李四'
}

//输出会发现直接将变量代表的值作为了属性名

symbol的更多用法访问

六、BigInt

前面我们说Number的最大数为2的53次方-1,这原本是Javascript 中可以用 Number 表示的最大数字。直到后来出现了BigInt,它可以表示任意大的整数
可以直接在数字后面加n表示这是一个bigint,也可以调用函数bigint()来定义。

const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);

需要注意的是它不能用Math对象中的方法,也不能和任何Number混算,必须转换为同一类型,并且注意bigint转换number时可能会丢失精度。

七、Object

Object是“属性的集合”。属性分为数据属性和访问器属性。都由key-value结果,key可以是字符传或是Symbol类型。
c++和java中,每个类都是一个类型,二者几乎等同。
而JavaScript 中的“类”仅仅是运行时对象的一个私有属性,而 JavaScript 中是无法自定义类型的。
JavaScript中的几个基本类型,都在对象类型中有一个亲戚。他们是:

  • Number
  • String
  • Boolean
  • Symbol

因此,3和new Number(3)是完全不同的值,一个是Number的值,一个是对象类型。
Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。
Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构造器。

JavaScript 语言设计上试图模糊对象和基本类型之间的关系,我们日常代码可以把对象的方法在基本类型上使用,比如:

  console.log("abc".charAt(0)); //a

甚至我们在原型上添加方法,都可以应用于基本类型,比如以下代码,在 Symbol 原型上添加了 hello 方法,在任何 Symbol 类型变量都可以调用。

    Symbol.prototype.hello = () => console.log("hello");
 
    var a = Symbol("a");
    console.log(typeof a); //symbol,a 并非对象
    a.hello(); //hello,有效

所以, . 运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对应对象的方法。

类型转换

JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换。大部分的类型转换是是符合我们直觉的,但我们也需要理解类型转换的规则,否则可能会造成一些代码中的判断失误。

一、== 和 ===

== 表示相等,会进行类型转换,如"3"==3?true:false //true
=== 表示严格相等,不会进行类型转换,也就是既比对值也比对数据类型。
== 的规则比较复杂,而且很多实践中禁止使用 ==,而要求显式转换后用 ===比较。
类型转换规则图:
image.png

二、装箱转换

每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。
全局的 Symbol 函数无法使用 new 来调用,但我们仍可以利用装箱机制来得到一个 Symbol 对象,我们可以利用一个函数的 call 方法来强迫产生装箱。

// MDN解释:call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
// 示例代码
//这里定义了一个方法
function Product(name, price) {
  this.name = name;
  this.price = price;
}
function Food(name, price) {
  //这里使用call 把this指向为自己的this 并调用方法,相当于在这个函数里使用了this.name = name,但this指向的是自己的this
  Product.call(this, name, price);
  this.category = 'food';
}
console.log(new Food('cheese', 5).name);
//所以这里能调用它的name

我们定义一个函数,函数里面只有 return this,然后我们调用函数的 call 方法到一个 Symbol 类型的值上,这样就会产生一个 symbolObject。
我们可以用 console.log 看一下这个东西的 typeof,它的值是 object,我们使用 symbolObject instanceof 可以看到,它是 Symbol 这个类的实例,我们找它的 constructor 也是等于 Symbol 的,所以我们无论从哪个角度看,它都是 Symbol 装箱过的对象:

var symbolObject = (function(){ return this; }).call(Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true

装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型做装箱转换。

    var symbolObject = Object(Symbol("a"));
 
    console.log(typeof symbolObject); //object
    console.log(symbolObject instanceof Symbol); //true
    console.log(symbolObject.constructor == Symbol); //true

每一类装箱对象皆有私有的 Class 属性,这些属性可以用 Object.prototype.toString 获取:

var symbolObject = Object(Symbol("a"));
 
console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]

在 JavaScript 中,没有任何方法可以更改私有的 Class 属性,因此 Object.prototype.toString 是可以准确识别对象对应的基本类型的方法,它比 instanceof 更加准确。
但需要注意的是,call 本身会产生装箱操作,所以需要配合 typeof 来区分基本类型还是对象类型。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值