原始类型和对象类型原始数据类型包括数字、布尔值、字符串、BigInt、null、undefined和后来添加的符号。这种数据类型的值是不可变的(immutable)。对象数据类型包含了我们常说的对象,对象的值是可变的。这是一个很大的类别。再细分的话,包括我们常用的数组(array)、函数(function)、Date、RegExp,以及后来加入的Map和Set。原始类型数:为什么0.1+0.2不等于0.3?JavaScript中的数字类型包括浮点数和整数。上述操作使用浮点数。定点数:好处是可以满足日常的小计算需求。缺点是在计算小数或大数时,会浪费大量空间。例如:14亿就是14亿。浮点数:用科学计数法表示,由三部分组成:尾数(significandmantissa)、基数(base)和指数(exponent)。例如:14亿就是1.4*10^9。JavaScript采用的IEEE754是二进制浮点运算的标准。本标准规定了四种浮点运算方法:单精度、双精度、扩展单精度和扩展双精度。JavaScript在这里选择了双精度(64位)方式,通常也称为double或float64类型。双精度(64位):有64位。它包含一个1位的符号位(sign),一个11位的偏置指数(exponent),和一个52位的小数部分(fraction)。因为十进制转二进制的算法是将十进制乘以2,直到没有小数为止,所以有些十进制的小数不能准确地表示为二进制小数。而且由于这里的浮点数都是二进制的,所以十进制数会存在精度损失的问题。而我们在使用加减法的时候,因为需要先对齐(也就是对齐指数,过程中还有移位),然后再计算,这个精度会进一步损失。并且根据JavaScript引擎实际返回的小数点后的位数,可能会缺少三分之一。这样一来,最终的结果就与实际的加减次数产生了偏差。解决方案:扩大规模,然后再缩小规模。NaN:如何判断一个值是否为数字?在IEEE754中,虽然NaN表示“不是数字”,但是如果我们使用typeofNaN来获取它,我们会发现它返回的是一个数字。原始类型有一个特点,就是两个具有相同值的数据会被认为是等价的。对象类型则相反。即使两个数据的值相同,也会被认为是不同的值,每个值都有唯一的标识。===123//Returntrue{}==={}//Returnfalse`NaN===NaN//Returnfalse`JavaScript会使用isNaN来判断一个值是否为数字,但是当我们输入字符串时,它也将被视为一个数字。因为在这个过程中,字符串“0”被转换成了数字。`isNaN("0")//returnfalse`**怎样才能更正确的判断一个值是否为数字呢?**isFinite是JavaScript中的一个内置函数,通过它,我们可以过滤掉NaN和Infinity。它会把括号里的值比如字符串转换成数字,所以我们需要用typeof来保证这个转换的问题不会遗漏varisNum=functionisNum(value){returntypeofvalue==='number'&&isFinite(value);}**string字符串:一串字符有多长?**我们使用像newString()这样的构造函数创建一个字符串。而当我们想要获取它的长度时,可以使用str.length方法来获取。varstr=newString("hello");str.length//return5;typeofstr//return'object'以字面方式获取字符串的长度(length)。当您使用typeof获取其类型时,您收到的结果仍然是一个字符串,而不是一个对象。varstr="hello";str.length//Return5typeofstr//Return'string'**booleanBoolean:你能分辨真假吗?**null:什么,你是对象吗?但是当我们使用typeof获取null的类型时,返回的结果是'object',也就是说它属于object类型。那么我们如何判断一个值是否为null呢?解决这个问题的办法不是用typeof,而是直接严格比较value和null。除了null,还有一个类似的是undefined。如果null表示该值是一个空对象,undefined表示没有值。但是当我们比较它们的值时,它们是相等的;另外,当我们严格比较它们的数据类型时,我们会发现它们是不同的。null==undefined//returntruenull==undefined//returnfalse那么我们什么时候用undefined,什么时候用null呢?通常我们不使用undefined,而是将其作为系统的返回值或系统异常。例如,当我们声明一个变量但不赋值时,结果是未定义的。而当我们要专门定义一个空对象时,可以使用null。对象类型为什么instanceOf会根据对象创建的实例返回错误?要创建一个对象,可以使用字面量值或构造函数方式Object.create()。在这种情况下,您无法使用instanceOf来确定新实例属于哪个对象。因为这里两个对象之间的关系更像是授权而不是继承,它们之间没有从属关系,所以返回错误。通过经典的基于原型的继承创建的实例可以通过instanceOf获得这种从属关系。以下示例://方法1:文字varobjA={name:"ObjectA"};varobjB=Object.create(objA);console.log(objBinstanceofobjA);//返回类型错误//方法2:constructorvarobjA=newObject();objA.name="ObjectA";varobjB=Object.create(objA);console.log(objBinstanceofobjA);//返回类型错误//经典的基于原型的继承varobjA=function(){/*这里有更多代码*/}objB=newobjA();console.log(objBinstanceofobjA);//返回真正的极客时间《Jvascript进阶实战课》学习笔记Day10
