浅谈Javascript数据类型

401 阅读5分钟

前言

js数据类型是前端面试经常被问到的问题,接下来我来讲讲我对数据类型的理解

js数据类型有哪几种

原始数据类型

原始数据类型:number(数字),string(字符串),Boolean(布尔),null(空),undefined(未定义),symbol,BigInt

注:Symbol是es6新增的,表示独一无二的值,BigInt也是新增的

引用类型

引用类型:function(函数),object(对象),Array(数组)

注:除了这三个是引用类型外,map set Weakmap Weakset RegExp Date Math 等也是引用类型

怎么检测数据类型 用typeof和instanceof

typeof

typeof:JavaScript一元操作符,用于以字符串的形式返回变量的原始类型

console.log(typeof 1) // 'number'
console.log(typeof '1') // 'string'
console.log(typeof undefined) // 'undefined'
console.log(typeof true) // 'boolean'
console.log(typeof Symbol() // 'symbol'

.....
console.log(typeof null) // 'Object'
console.log(typeof {}) // 'Object'
console.log(typeof [1,2,3]) // 'Object'
console.log(typeof function) // 'function'

注:typeof null // 'object' ,所以判断不了null,这是js本身的一个bug。因为不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“object”。

注:typeof不太好判断引用类型, typeof “引用类型” 除了function 可以判断为 'function' ,其他都是'Object'

instanceof

instanceof:JavaScript操作符,会在原型链中的构造器中搜索,找到则返回true,否则返回false

let a = { name: 'true' }
let b = [1, 2, 3]
let c = function() {}
...
console.log(a instanceof Object) // true
console.log(b instanceof Array) // true
console.log(c instanceof Function) // true
console.log(b instanceof Function) // false
console.log(a instanceof Array) // false
...

js数据类型之间的转换

显示类型转换:

  1. Number():在ES5规范中定义了抽象操作ToNumber
    • Undefined类型的值转换为NaN
    • Null类型的值转换为0
    • String类型的值转换需要使用Number()函数进行转换,如果包含非数字值则转换为NaN,空字符串为0
    • Boolean类型的值,true转换为1,false转换为0
    • Symbol类型的值不能转换为数字,会报错
console.log(Number()) // 0
console.log(Number(null)) //0
console.log(Number(false)); // 0
console.log(Number(true));  // 1
console.log(Number(123)); // 123
console.log(Number(000123)); // 123
console.log(Number(' ')); // 0
console.log(Number(undefined)); //NaN
console.log(Number('aaaa')); // NaN
console.log(Number(Symbol())); // TypeError

  1. String():都能转成字符串
console.log(String(123)) // '123'
console.log(String(null) // 'null'
console.log(String(a)) // 'a'
console.log(String(undefined)) // 'undefined'
console.log(String(NaN)) // 'NaN'
...
  1. toString(): undefined 与 null 不能被转字符串
console.log(toString(123)) // '123'
console.log(toString(null) // 'null'
console.log(toString(a)) // 'a'
console.log(toString(undefined)) // 'undefined'
console.log(toString(NaN)) // 'NaN'
console.log(toString(undefined)) // [object Undefined]
console.log(toString(null)) // [object Undefined]
  1. boolean(): 转Boolean值
console.log(Boolean()) // false
console.log(Boolean(false))  // false
console.log(Boolean(null))  // false
console.log(Boolean(undefined))  // false
console.log(Boolean(NaN))  // false
console.log(Boolean(-0))  // false
console.log(Boolean(+0))  // false
console.log(Boolean('')) // false

console.log(Boolean(1)) // true
console.log(Boolean('a')) // true
console.log(Boolean({})) // true
console.log(Boolean([])) // true

注:转换为Boolean():0  ''(空字符串) null undefined NaN 会转换成false  其它都会转换成true

隐式类型转换:

  1. 一元操作符:一元操作符会默认调用 TONumber 处理该值。如果传入的值是对象类型,会先调用ToPrimitive()方法,执行的步骤是:
    • 如果 该值 是基本类型,就直接返回
    • 否则,调用 valueOf 方法,如果返回一个原始值,则js将其值返回
    • 否则,调用 toString 方法,如果返回一个原始值,则js将其值返回
    • 否则,报类型错误
console.log(1 + '1'); // '11'
console.log(+'1'); // 1
console.log(+ []); // 0
console.log(+ ['1']); // 1
console.log(+ ['1','2']); // NaN
console.log(+ {}); // NaN
  1. 二元运算符: 例如 val1 + val2 遵循如下规则:
    • v1 = ToPrimitive(val1)
    • v2 = ToPrimitive(val2)
    • 如果v1是字符串或者v2是字符串,那么返回 ToString(v1) 和 ToString(v2) 的拼接结果
    • 否则返回 ToNumber(v1) 和 ToNumber(v2) 的运算结果
console.log([] + 1) // 0 + 1 => 1
console.log(null + 1) // 0 + 1 => 1
console.log(1 + true);// 1 + 1 => 1
console.log(1 + '1') // '11'
...
  1. == 相等 与 != 不相等: 在转换操作数的类型时,遵循如下规则:
    • 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。fase转为0,true转为1
    • 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转为数值,再比较是否相等
    • 如果一个操作数是对象,另一个不是,则调用对象的valueOf()方法取得原始值,在根据前面规则比较
    • 如果有任一操作数是NaN,==操作符则返回 false,!=操作符返回true
    • 如果两个操作数都是对象,则比较他们是不是同一个对象。如果两个操作数都指向同一个对象,则相等返回true。否则,两者不相等

注:即使两个操作数都是NaN,相等操作符也返回false,因为按照规则,NaN不等于NaN

注:undefined 与 null 比较特殊,会遵循如下规则:1, null 与 undefined相等。2, nul 和 undefined 不能转换为其他类型的值再进行比较

console.log( null == undefined) // true
console.log( "NaN == NaN ) // false
console.log( 1 == NaN) // false
console.log( NaN == NaN) // false
console.log( NaN != NaN) // true
console.log( false == 0) // true
console.log( true == 1 ) // true
console.log( true == 2 ) // false
console.log( undefined == 0) // false
console.log( null == 0 ) // false
console.log( '1' == 1 ) // true
  1. === 全等!== 不全等: 与前面的 == 和 != 相比,会比较数据类型
let a = ('11' == 11) // true, 转换后相等
let b = ('11' === 11) // false, 不相等,因为数据类型不同

let c = ('11' != 11) // false, 转换后相等
let d = ('11' !== 11) // true, 不相等, 因为数据类型不同 
  1. 布尔值其他类型:当一方出现布尔值时,就会对这一方面的值进行 ToNumber() 处理
console.log(1 + true) // 2
console.log(1 - true) // 0
console.log(1 + false) // 1

总结

以上就是我对javascript数据类型的理解,如有不对之处欢迎大家指正。 这是我的第一篇文章,希望大家多多支持点赞。谢谢大家。