共计 3868 个字符,预计需要花费 10 分钟才能阅读完成。
数据类型整顿
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)
打印后果为
30
20
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) // true
let man = new String("Human");
console.log(man instanceof String) // true
let 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)) // false
console.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); // 1
Number(false); // 0
Number('0111'); //111
Number(null); //0
Number(''); //0
Number('1a'); //NaN
Number(-0X11); //-17
Number('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(),如果转换为根底类型,则返回;
- 如果都没有返回根底类型,会报错。