数据类型排列js数据类型是8种基本类型undefined,Null,Boolean,String,Number,Symbol,BigInt引用数据类型是Object,常用引用类型有Array,RegExp,Date,数学,函数。基本数据类型存储在栈内存中。当它被引用或复制时,会创建一个完全相等的变量引用类型,并存储在堆内存中。地址已存储。多个引用指向同一个地址,处于“共享”状态。对象+函数示例leta={nae:'jake',age:18}functionchange(e){e.age=20e={name:'tom',age:30}returne}letb=change(A);console.log(b.age)console.log(a.age)打印3020函数第一行代码改变了a对象的age属性的结果,但是returne把新对象e={name:'tom',age:30}地址返回给b,如果函数没有返回,打印第一行会提示未定义数据类型检测第一种检测方法,typeoftypeof1//'number'typeof'1'//'string'typeofundefined//'undefined'typeoftrue//'boolean'typeofSymbol()//'symbol'typeofnull//'object',js遗留bug,不代表null是引用数据类型,也不是不是对象typeof[]//'object'typeof{}//'object'typeofconsole//'object'typeofconsole.log//'function'第二种检测方法instanceofletHuman=function(){};letwomen=newHuman()console.log(womeninstanceofHuman)//trueletman=newString("Human");console.log(maninstanceofString)//trueletstr="abc";console.log(strinstanceofString)//false根据现有的instanceofFeatures,实现一个myinstanceofffunctionmyinstanceof(val,typeName){if(typeofval!=='object'||值===null)returnfalse//getPrototypeOf用于获取参数原型对象letproto=Object.getPrototypeOf(val);while(true){if(proto===null)返回false;如果(原型===类型名称.原型)返回真;proto=Object.getPrototypeOf(proto)}}console.log(myinstanceof('123',String))//falseconsole.log(myinstanceof(newString('123'),String))//从上面我们知道typeof和instanceof在类型判断上都有问题。instanceof可以准确判断复杂引用数据类型,但不能正确判断基本数据类型;typeof可以判断基本数据类型(null除外),但是引用数据类型除了函数类型,第三种检测方法Object.prototype.toStringObject.prototype.toString({})//"[objectObject]"Object.prototype.toString.call({})//"[objectObject]"Object.prototype.toString.call(1)//"[objectNumber]"Object.prototype.toString.call('1')//"[objectString]"Object.prototype.toString.call(true)//"[objectBoolean]"Object.prototype.toString.call(function(){})//"[objectFunction]"Object.prototype.toString.call(null)//[objectNull]"Object.prototype.toString.call(undefined)//[objectUndefined]"Object.prototype.toString.call(/123/g)//"[objectRegExp]"Object.prototype.toString.call(newDate())//[objectDate]"Object.prototype.toString.call([])//"[objectArray]"Object.prototype.toString.call(document)//"[objectHTMLDocument]"Object.prototype.toString.call(window)//“[objectWindow]”的基本子方法特性,可以实现一个获取数据类型的方法functiongetType(val){lettype=typeofval;//基本数据类型直接返回if(type!=="object")returntype//objectreturnObject.prototype.toString.call(obj).replace(/^\[object(\S+)\]$/,'$1');//注意有个空格}类型转换规则Number()方法强制转换规则如果是布尔值,则true和false分别转换为1和0;如果它是一个数字,返回它自己;如果为空,则返回0;如果未定义,则返回NaN;如果是字符串,则遵循以下规则:如果字符串中只包含数字(或者是一串以0X/0x开头的十六进制数字,允许加号和减号),则将其转换为十进制;如果字符串包含包含有效的浮点格式,则将其转换为浮点值;如果是空字符串,则将其转换为0;如果不是上述格式的字符串,则返回NaN;如果是Symbol,则抛出错误;如果是对象,并且部署了[Symbol.toPrimitive],则调用该方法,否则调用对象的valueOf()方法,然后将返回值按照前面的规则进行转换;如果转换结果为NaN,则调用对象的toString()方法,再次按照之前的顺序转换返回相应的值(对象转换规则将在后面详细介绍)Number(true);//1号(假);//0号('0111');//111号(空);//0号('');//0号('1a');//NaNNumber(-0X11);//-17Number('0X11')//17Boolean()方法的转换规则规则:除undefined、null、false、''、0(包括+0、-0)、NaN转为false外,其他为true。隐式类型转换通过逻辑运算符(&&、||、!)、运算符(+、-、*、/)、关系运算符(>、<、<=、>=)、相等运算符(==)或if/while条件运算,如果两个数据类型不相同,会有隐式类型转换'=='隐式类型转换规则如果类型相同,则不需要进行类型转换;如果其中一个运算符的值为null或undefined,那么另一个运算符必须为null或undefined才返回true,否则都返回false;如果其中之一是Symbol类型,则返回false;如果两个操作值都是字符串和数字类型,那么字符串会被转换为数字;如果操作值是布尔值,它将被转换为数字;如果一个操作值是object,另一个是string、number或symbol,则在判断之前将object转换为原始类型(调用object的valueOf/toString方法进行转换)。'+'的隐式类型转换规则'+'运算符不仅可以用于数字相加,还可以用于字符串连接。只有当‘+’号两边都是数字时,才进行加法运算;如果两边都是字符串,则直接拼接,不进行隐式类型转换。如果其中一个为字符串,另一个为undefined、null或Boolean,则调用toString()方法进行字符串拼接;如果是纯对象、数组、正则表达式等,默认调用对象的转换方法会优先(下一讲会具体介绍),再进行拼接。如果其中一个为数字,另一个为undefined、null、Boolean或number,则会转为数字进行加法运算。对象参照前面的规则。如果其中一个是字符串,另一个是数字,则按照字符串规则进行拼接。对象转换规则对象转换规则会先调用内置的[ToPrimitive]函数,规则逻辑如下:如果部署了Symbol.toPrimitive方法,则先调用后返回;调用valueOf(),如果转换为基本类型,则返回;调用toString(),如果转换为基本类型,则返回;如果不返回基本类型,就会报错。
