数据类型整顿
js数据类型为8种
根底类型 undefined
,Null
,Boolean
,String
,Number
,Symbol
,BigInt
援用数据类型为Object
,常见的援用类型为Array
,RegExp
,Date
,Math
,Function
。
- 根底数据类型存储在
栈内存
,被援用或者拷贝时,会创立衣蛾齐全相等的变量 - 援用类型存储在
堆内存
,存储的是地址,多个援用指向同一个地址,处于“共享”的状态。
一个对象+function例子
let a = { nae:'jake', age:18}function change (e){ e.age = 20 e = { name :'tom', age:30 } return e}let b = change(a);console.log(b.age)console.log(a.age)
打印后果为
3020
function中第一行代码扭转了a对象的age属性,然而return e把新对象e={name:'tom',age:30}地址返回给了b,如果function没有return,第一行打印会提醒undefined
数据类型检测
第一种检测形式,typeof
typeof 1 // 'number'typeof '1' // 'string'typeof undefined // 'undefined'typeof true // 'boolean'typeof Symbol() // 'symbol'typeof null // 'object',js遗留BUG,不代表null是援用数据类型,也不是对象typeof [] // 'object'typeof {} // 'object'typeof console // 'object'typeof console.log // 'function'
第二种检测形式instanceof
let Human = function(){};let women = new Human()console.log(women instanceof Human) // truelet man = new String("Human");console.log(man instanceof String) // truelet str = "abc";console.log(str instanceof String) // false
依据instanceof
现有的个性,实现一个myinstanceof
function myinstanceof(val,typeName) { if(typeof val !== 'object' || val === null) return false // getPrototypeOf用于拿到参数原型对象 let proto = Object.getPrototypeOf(val); while(true){ if(proto === null) return false; if( proto === typeName.prototype) return true; proto = Object.getPrototypeOf(proto) }}console.log(myinstanceof('123',String)) // falseconsole.log(myinstanceof(new String('123'),String)) // true
以上得悉,typeof
和instanceof
两种判断类型的形式都存在问题
- instanceof 能够精确地判断简单援用数据类型,然而不能正确判断根底数据类型;
- typeof 能够判断根底数据类型(null 除外),然而援用数据类型中,除了 function 类型以外,其余的也无奈判断
第三种检测形式Object.prototype.toString
Object.prototype.toString({}) // "[object Object]"Object.prototype.toString.call({}) // "[object Object]"Object.prototype.toString.call(1) // "[object Number]"Object.prototype.toString.call('1') // "[object String]"Object.prototype.toString.call(true) // "[object Boolean]"Object.prototype.toString.call(function(){}) // "[object Function]"Object.prototype.toString.call(null) //"[object Null]"Object.prototype.toString.call(undefined) //"[object Undefined]"Object.prototype.toString.call(/123/g) //"[object RegExp]"Object.prototype.toString.call(new Date()) //"[object Date]"Object.prototype.toString.call([]) //"[object Array]"Object.prototype.toString.call(document) //"[object HTMLDocument]"Object.prototype.toString.call(window) //"[object Window]"
根本次办法特点,能够实现一个获取数据类型的办法
function getType(val) { let type = typeof val; // 根底数据类型间接返回 if (type !== "object") return type // object return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1'); // 留神正则两头有个空格}
类型转换规定
Number() 办法的强制转换规则
- 如果是布尔值,true 和 false 别离被转换为 1 和 0;
- 如果是数字,返回本身;
- 如果是 null,返回 0;
- 如果是 undefined,返回 NaN;
- 如果是字符串,遵循以下规定:如果字符串中只蕴含数字(或者是 0X / 0x 结尾的十六进制数字字符串,容许蕴含正负号),则将其转换为十进制;如果字符串中蕴含无效的浮点格局,将其转换为浮点数值;如果是空字符串,将其转换为 0;如果不是以上格局的字符串,均返回 NaN;
- 如果是 Symbol,抛出谬误;
- 如果是对象,并且部署了 [Symbol.toPrimitive] ,那么调用此办法,否则调用对象的 valueOf() 办法,而后根据后面的规定转换返回的值;如果转换的后果是 NaN ,则调用对象的 toString() 办法,再次按照后面的程序转换返回对应的值(Object 转换规则会在上面细讲)。
Number(true); // 1Number(false); // 0Number('0111'); //111Number(null); //0Number(''); //0Number('1a'); //NaNNumber(-0X11); //-17Number('0X11') //17
Boolean() 办法的强制转换规则
规定:除了 undefined、 null、 false、 ''、 0(包含 +0,-0)、 NaN 转换进去是 false,其余都是 true。
隐式类型转换
但凡通过逻辑运算符 (&&、 ||、 !)、运算符 (+、-、*、/)、关系操作符 (>、 <、 <= 、>=)、相等运算符 (==) 或者 if/while 条件的操作,如果遇到两个数据类型不一样的状况,都会呈现隐式类型转换
'==' 的隐式类型转换规定
- 如果类型雷同,毋庸进行类型转换;
- 如果其中一个操作值是 null 或者 undefined,那么另一个操作符必须为 null 或者 undefined,才会返回 true,否则都返回 false;
- 如果其中一个是 Symbol 类型,那么返回 false;
- 两个操作值如果为 string 和 number 类型,那么就会将字符串转换为 number;
- 如果一个操作值是 boolean,那么转换成 number;
- 如果一个操作值为 object 且另一方为 string、number 或者 symbol,就会把 object 转为原始类型再进行判断(调用 object 的 valueOf/toString 办法进行转换)。
'+' 的隐式类型转换规定
- '+' 号操作符,不仅能够用作数字相加,还能够用作字符串拼接。仅当 '+' 号两边都是数字时,进行的是加法运算;如果两边都是字符串,则间接拼接,毋庸进行隐式类型转换。
- 如果其中有一个是字符串,另外一个是 undefined、null 或布尔型,则调用 toString() 办法进行字符串拼接;如果是纯对象、数组、正则等,则默认调用对象的转换方法会存在优先级(下一讲会专门介绍),而后再进行拼接。
- 如果其中有一个是数字,另外一个是 undefined、null、布尔型或数字,则会将其转换成数字进行加法运算,对象的状况还是参考上一条规定。
- 如果其中一个是字符串、一个是数字,则依照字符串规定进行拼接。
Object 的转换规则
对象转换的规定,会先调用内置的 [ToPrimitive] 函数,其规定逻辑如下:
- 如果部署了 Symbol.toPrimitive 办法,优先调用再返回;
- 调用 valueOf(),如果转换为根底类型,则返回;
- 调用 toString(),如果转换为根底类型,则返回;
- 如果都没有返回根底类型,会报错。