JS 中的类型 & 类型判断 & 类型转换

简介: JS 中的类型 & 类型判断 & 类型转换

image.png


一、内置类型

JS 中有 8 种内置类型,⼜分为两⼤类型: 7 种【基本类型】 和 【对象或复杂类型】:

  • 基本类型: null , undefined , boolean , number , string , symbol , bigInt .
  • 对象或复杂类型: array , object , function .
  • PS:  undefined 派生自 null 但它们的意义是不一样的. undefined 指定义了变量却未初始化. null 指定义了当前变量且这个变量未来是用于存储 object 类型的值.

注意:对于【基本类型】来说,如果使⽤字⾯量的⽅式,那么这个变量只是个字⾯量,只有在必要的时候才会转换为对应的类型.

let num = 666;
num.toString(); // 虽然 num 属于基本类型,但是它可以调用方法,并且不会报错
// 上面相当于
// 1. 字面量声明
let num = 666;
// 2. 转为对应构造函数的实例, 并调用方法, 调用结束后,直接删除生成的这个实例
new Number(num).toString();
复制代码

二、类型判断 — typeof & instanceof &  Object.prototype.toString.call(obj)

typeof

直接看判断结果

// 基本类型
console.log(typeof null);          // object
console.log(typeof undefined);     // undefined
console.log(typeof true);          // boolean
console.log(typeof '666');         // string
console.log(typeof 1);             // number
console.log(typeof 1n);            // bigint
console.log(typeof Symbol());      // symbol
// 复杂类型
console.log(typeof []);                // object
console.log(typeof {});                // object
console.log(typeof function add(){});  // function   
复制代码

从以上判断结果可以看出来:

  • 基本类型中除了对 null 的判断错误之外,其他的都是正常的.
  • PS: 【typeof null 为 object,是因为最初的 js 版本使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,其中 000 开头的代表的是对象,然而 null 是用全 0 表示,所以将它错误的判断为 object 】
  • 复杂类型中除了对 function 和 {} 类型判断正确之外,其他的都是错误的.

instanceof

用于判断一个变量是否属于某个对象的实例,既然是实例意味着该变量是通过 new 操作得到的.

var bool = new Boolean(true);
    var str = new String('666');
    var num = new Number(1);
    var date = new Date();
    var reg = new RegExp(/.+/);
    var arr = new Array();
    var obj = new Object({});
    var add = function () {}
    console.log(bool instanceof Boolean);           // true
    console.log(str instanceof String);             // true
    console.log(num instanceof Number);             // true
    console.log(date instanceof Date);              // true
    console.log(reg instanceof RegExp);             // true
    console.log(arr instanceof Array);              // true
    console.log([] instanceof Array);               // true
    console.log(obj instanceof Object);             // true
    console.log({} instanceof Object);              // true
    console.log(add instanceof Function);           // true
    // 自定义类
    class Person{
      constructor(name){
        this.name = name;
      }
    }
    var person = new Person('zs'); 
    console.log(person instanceof Person);        // true
复制代码
  • 注意:null、undefined、symbol、bigint 没有自己专属的构造函数,因此不可以进行 new 操作,所以不适用于 instanceof 判断
  • 作用:
  • 判断某个实例是否属于某构造函数
  • 在继承关系中用来判断一个实例是否属于它的父类型或者祖先类型的实例
  • 如:left instanceof right ,只要  right.prototype  存在于 left.__proto__ 的原型链上,则会返回 true , 否则返回 false .
  • 缺点:
  • 并不适用于所有的类型
  • 由于它依赖于构造函数去判断,所以当某个实例的构造函数指向被强行修改,那么判断将出现错误

Object.prototype.toString.call(obj)

使用以上方式可以很好的区分各种类型:(无法区分自定义对象类型,自定义类型可以采用 instanceof 区分)

console.log(Object.prototype.toString.call("str"));   //[object String]
console.log(Object.prototype.toString.call(1));        //[object Number]
console.log(Object.prototype.toString.call(true));      //[object Boolean]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(null));      //[object Null]
console.log(Object.prototype.toString.call({name: "zs"})); //[object Object]
console.log(Object.prototype.toString.call(function(){}));   //[object Function]
console.log(Object.prototype.toString.call([]));  //[object Array]
console.log(Object.prototype.toString.call(new Date));  //[object Date]
console.log(Object.prototype.toString.call(/\d/));  //[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));  //[object Object]
复制代码
  • 为什么不直接使用 obj.toString() ?
  • 因为 toString 是 Object.prototype 上的方法,而 Array、Function 等类型虽然作为 Object 的实例,但它们都重写了 toString 方法,因此 obj.toString() 直接调用只能得到重写后的值.
console.log(({}).toString()); // [object Object]
console.log("zs".toString()); // zs
console.log((1).toString()); // 1
console.log([1,2].toString()); // 1,2
console.log(new Date().toString()); // Thu Oct 14 2021 22:25:11 GMT+0800 (中国标准时间)
console.log(function(){}.toString()); // function (){}
console.log(null.toString()); // error
console.log(undefined.toString()); // error
复制代码
  • 如果删除了被重写的 toString 后,可以发现结果和 Object.prototype.toString.call(obj) 是一致的
var arr = [1, 2, 3];
   var func = function (){};
   // 调用重写的 toString
   console.log(Array.prototype.hasOwnProperty("toString")); //true
   console.log(Function.prototype.hasOwnProperty("toString")); //true
   console.log(arr.toString()); //  '1,2,3'
   console.log(func.toString()); // 'function (){}'
   // delete 操作符删除实例属性
   delete Array.prototype.toString;
   delete Function.prototype.toString;
   // 本质上是调用 Object.prototype.toString
   console.log(Array.prototype.hasOwnProperty("toString")); //false  
   console.log(Function.prototype.hasOwnProperty("toString")); //false
   console.log(arr.toString()); // "[object Array]"
   console.log(func.toString()); // "[object Function]"
复制代码

三、类型转换

转 Boolean

在条件判断时,除了undefined ,null , false , NaN , '' , 0 , -0 ,其他所有值都转为 true ,包括所有对象。

对象转基本类型

  • 对象在转换基本类型时,⾸先会调⽤ valueOf ,然后调⽤ toString 。并且这两个⽅法是可以被重写的。
  • 当然你也可以重写 Symbol.toPrimitive ,该⽅法在转基本类型时调⽤优先级最⾼。

四则运算符(+、-、*、/)

  • 只有当加法运算时,其中⼀⽅是字符串类型,就会把另⼀个也转为字符串类型。
  • 其他运算只要其中⼀⽅是数字,那么另⼀⽅就转为数字。
  • 并且加法运算会触发三种类型转换:将值转换为原始值,转换为数字,转换为字符串。
1 + '1' // '11'
2 * '2' // 4
[1, 2] + [2, 1] // '1,22,1'
// [1, 2].toString() -> '1,2'
// [2, 1].toString() -> '2,1'
// '1,2' + '2,1' = '1,22,1'
复制代码
  • 对于加号需要注意这个表达式 'a' + + 'b'
'a' + + 'b' // -> "aNaN"
// 因为 + 'b' -> NaN
// 你也许在⼀些代码中看到过 + '1' -> 1
复制代码

== 操作符

例子:x == y

  • x,y 为 number || string => 先把 string 转 number ,后进行比较
  • x,y 为 number || boolean => 先把 boolean 转 number ,后进行比较
  • 任何与 NaN 进行的比较都返回 false
  • x,y 为 string || boolean => 先把 string 和 boolean 转 number ,后进行比较
  • x,y 为 undefined || null => 返回 true
  • x,y 为 number => -0 == +0 返回 true ,其他正负不相等
  • x,y 为 (number || string) || object => 先把 object 转基本类型,后进行对比
  • object => [Symbol.toPrimitive] () || valueOf() || toString()
  • x,y 为 boolean || object => 先把 boolean 转 number ,按上述规则 5 比较

> || < || =< || => 比较运算符

  • x,y 为 object || other => object 转成 基本类型,然后比较
  • x,y 为 string => 通过 unicode 字符索引来⽐较


目录
相关文章
|
1天前
|
JavaScript
常见函数的4种类型(js的问题)
常见函数的4种类型(js的问题)
12 0
|
1天前
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
47 0
|
1天前
|
JavaScript 前端开发
JavaScript 中如何检测一个变量是一个 String 类型?
JavaScript 中如何检测一个变量是一个 String 类型?
23 2
|
1天前
|
JSON JavaScript 前端开发
抓住异常,解救你的代码世界:你应该了解的 JavaScript 异常类型
抓住异常,解救你的代码世界:你应该了解的 JavaScript 异常类型
|
1天前
|
Web App开发 前端开发 JavaScript
在 Chrome 开发者工具里配置哪些类型的 JavaScript 文件应该被调试器忽略
在 Chrome 开发者工具里配置哪些类型的 JavaScript 文件应该被调试器忽略
6 0
|
1天前
|
存储 JavaScript 前端开发
JavaScript 中松散类型的理解
JavaScript 中松散类型的理解
7 1
|
1天前
|
JavaScript 前端开发
JS中运算符的算术、赋值、+、比较(不同类型之间比较)、逻辑
JS中运算符的算术、赋值、+、比较(不同类型之间比较)、逻辑
9 1
|
1天前
|
前端开发 JavaScript 索引
【Web 前端】JS的几种具体异常类型(报错)
【4月更文挑战第22天】【Web 前端】JS的几种具体异常类型(报错)
|
1天前
|
JavaScript 前端开发 Python
javascript中的强制类型转换和自动类型转换
javascript中的强制类型转换和自动类型转换
|
1天前
|
数据可视化 JavaScript 前端开发
Echarts是一个开源的JavaScript可视化库,用于创建各种类型的图表
Echarts是JavaScript的开源可视化库,Python通过Pyecharts库可调用它来绘制图表。示例展示了如何用Pyecharts创建柱状图:定义图表对象,设置标题和坐标轴,添加X轴、Y轴数据,最后渲染展示。Pyecharts还支持折线图、散点图、饼图等多种图表类型,更多详情可查阅官方文档。
32 0