数据类型

  • 原始类型:在栈中存储,占空间大小固定
    • Boolean:布尔值,truefalse
    • null:空对象
    • undefined:未赋值,声明为定义的变量会返回undefined,注意:undefined不是 JS 的保留关键字,所以可以最为变量名使用,如果想获取安全的undefined值可以使用void 0
    • Number:数字
    • String:字符串
    • Symbol:ES6 新添加数据类型,它的实例是唯一且不可改变的
    • BigInt:供了一种方法来表示任意精度整数,及时超过Number能够表示的安全范围
  • 引用类型:数据存储在堆,栈存储堆的指针
    • Object:对象
      • Array
      • Map
      • Set
      • Date
      • RegExp
      • Error

数据类型检测

typeof

// 原始类型
typeof 123 // "number"
typeof NaN // "number"
typeof 1n // "bigint"
typeof '123' // "string"
typeof false // "boolean"

// 函数
function f() {}
typeof f // "function"

// undefined
typeof undefined // "undefined"

// 其他类型都返回"object"
typeof window // "object"
typeof {} // "object"
typeof [] // "object"
typeof null // "object"

NaN

NaN(Not a Number)非数字,是一个特殊的数值,是一个警戒值,当数值计算出错的情况下结果就是NaNNaN是 JS 中唯一一个非自反的,即:NaN !== NaN。 因为typeof NaN === 'number',所以使用typeof判断是否为数字是不可靠的,需要使用isNaN()函数判断是否是有效数值。

  • isNaN(value): boolean:会首先尝试将传入的值转换为数字类型,不能转换为数字的一律返回true
  • Number.isNaN(value): boolean:会首先判断是否为数字,如是数值再判断是否为NaN
isNaN('a') // true
Number.isNaN('a')  //false

Object.prototype.toString

使用Object对象的原型方法,而不能直接使用对象的toSting()方法,因为可能被重写。

Object.prototype.toString.apply(1); //[object Number]
  • 数值:返回[object Number]
  • 字符串:返回[object String]
  • 布尔值:返回[object Boolean]
  • undefined:返回[object Undefined]
  • null:返回[object Null]
  • 数组:返回[object Array]
  • arguments 对象:返回[object Arguments]
  • 函数:返回[object Function]
  • Error 对象:返回[object Error]
  • Date 对象:返回[object Date]
  • RegExp 对象:返回[object RegExp]
  • 其他对象:返回[object " + 构造函数的名称 + "]

instanceof

instanceof可以判断对象的类型,原理是:在对象的原型链中是否能找到检测的对象

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false
console.log('str' instanceof String);                // false

console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true
function myInstanceof(left, right) {
  // 获取对象的原型
  let prototype = Object.getPrototypeOf(left)
  // 获取构造函数的 prototype 对象
  let targetPrototype = right.prototype;

  // 判断构造函数的 prototype 对象是否在对象的原型链上
  while (true) {
    if (!prototype) return false;
    if (prototype === targetPrototype) return true;
    // 如果没有找到,就继续从其原型上找,Object.getPrototypeOf方法用来获取指定对象的原型
    prototype = Object.getPrototypeOf(prototype);
  }
}

数据类型转换

强制转换

  • Number()
    • 数值 => 原值
    • 字符串
      • 空字符串转化为0
      • 数字字符串转换为相应数值
      • 其它转换为NaN
    • 布尔值 => true -> 1false -> 0
    • undefined => NaN
    • null => 0
    • object:
      • 先调用对象自身的valueOf()方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number()方法,不再进行后续步骤。
      • 如果valueOf()方法返回复合类型的值,再调用对象自身的toString()方法,如果toString()方法返回原始类型的值,则对该值使用Number()方法,不再进行后续步骤。
      • 如果toString()方法返回的是复合类型的值,则报错。
  • String():
    • 数值 => 相应字符串
    • 字符串 => 原值
    • 布尔值 => true->'true'false->'false'
    • undefined => 'undefined'
    • null => 'null'
    • object
      • 先调用toString()方法,如果toString()方法返回的是原始类型的值,则对该值使用String()方法,不再进行以下步骤。
      • 如果toString()方法返回的是复合类型的值,再调用valueOf()方法,如果valueOf()方法返回的是原始类型的值,则对该值使用String()方法,不再进行以下步骤。
      • 如果valueOf()方法返回的是复合类型的值,则报错。
  • Boolean():JavaScript 把nullundefined0NaN和空字符串''视为false,其他值一概视为true

自动转换

自动类型转换的原则是预期什么类型的值就会调用该类型的转换函数,以下三种情况会自动进行类型转换:

  • 不同类型的数据相互运算
    • 加法运算:只要有一个为字符串类型,就全部转换为字符串,进行字符串拼接
    • 其他算数运算符:一律使用Number()进行转换
  • 使用非布尔类型遍历进行条件判断:使用Boolean()转换
  • 对非数字类型变量使用一元运算符(+-):使用Number()转换

results matching ""

    No results matching ""