JavaScript之数据类型

一.数据类型

JavaScript中有7中数据类型,分为基本数据类型和引用数据类型两大类:

1.基本数据类型

  • Number(数字):整数或浮点数,例如3.14-42

  • String(字符串):字符串是一系列字符,例如"Hello, World!"

  • Boolean(布尔值):表示真或假,例如truefalse

  • Null(空值):表示没有值,例如null

  • Undefined(未定义):表示未定义的值,例如undefined

  • Symbol(符号):表示唯一的标识符,例如Symbol('example)

2.引用数据类型

  • Object(对象):是一组属性和方法的集合,例如{ name: 'Alice', age: 30 }

  • Array(数组):是一个有序的集合,例如[1, 2, 3]

  • Function(函数):是一段可重复使用的代码块,例如function add(a, b) { return a + b; }

  • Date(日期):表示日期和时间,例如new Date()

  • RegExp(正则表达式):用于匹配字符串的模式,例如/\d+/g

3.基本数据类型和引用数据类型区别

  • 基本数据类型存在于(stack)中,是不可变的,修改一个基本数据类型的值,实际上会创建一个新的值。

  • 引用数据类型存在于(heap)中,是可变的,引用数据类型的变量实际上是对值得引用,而不是值本身。

    • 例如:如果两个变量引用同一个对象,当一个变量修改该对象时,另一个变量也会受到影响。
  • 注:堆和栈的概念存在于数据结构和操作系统内存中,在数据结构中:

    • 在数据结构中,栈中数据的存取方式为先进后出。

    • 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。

4.判断数据类型的方法

  • typeof操作符
console.log(typeof 123); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof function(){}); // function

typeof操作符用于检测变量的数据类型,返回一个字符串,其值为变量的数据类型。它能够正确地判断基本数据类型的数据类型,但不能用于判断引用类型,因为它会统一返回为object

  • instanceof操作符
console.log(new String("hello") instanceof String); // true
console.log(123 instanceof Number); // false
console.log(new Number(123) instanceof Number); // true
console.log(true instanceof Boolean); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log({} instanceof Object); // true
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true

instanceof操作符用于检测一个对象是否为某个类的实例,它的原理是检查对象的原型链中是否存在指定类的原型。它不能用于判断基本数据类型。

  • Object.prototype.toString.call()方法
console.log(Object.prototype.toString.call(123)); // [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({})); // [object Object]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(function(){})); // [object Function]

Object.prototype.toString方法用于返回一个表示对象类型的字符串。它的原理是获取对象的内部[[Class]]属性,并将其转换为字符串形式。所有对象的内部[[Class]]属性都可以通过Object.prototype.toString.call(obj)方法获取。

  • constructor属性
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

constructor 属性返回对象的构造函数。每个对象(除 nullundefined)都有一个constructor属性,可以通过该属性获取对象的构造函数。由于每个数据类型都对应一个构造函数,因此可以通过判断变量的 constructor 属性来判断变量的数据类型。

5.判断数组的方法

  • instanceof 运算符
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
  • Array.isArray() 方法
let arr = [1, 2, 3];
console.log(Array.isArray(arr)); // true

Object.prototype.toString.call() 方法

let arr = [1, 2, 3];
console.log(Object.prototype.toString.call(arr) === "[object Array]"); // true

注意: 第一种和第二种方式的效率较高,并且可以处理跨 iframe 的情况。第三种方式会出现误判,例如当一个类似数组的对象使用 Object.prototype.toString.call() 方法判断时,也会返回 “[object Array]”,因此需要谨慎使用。

6.instanceof的原理和实现

instanceof用于检查一个对象是否是另一个对象的实例。它的语法如下:

object instanceof constructor //object是要检查的对象,constructor是一个函数或类,表示要检查的类型。
  • 原理

    instanceof的原理是检查object的原型链上是否存在constructor.prototype。如果object的原型链上存在constructor.prototype,则objectconstructor的实例,否则不是。

  • 实现

    下面是一种基于原型链的实现instanceof的方法:

function myInstanceOf(object, constructor) {
  let proto = Object.getPrototypeOf(object);
  while (proto) {
    if (proto === constructor.prototype) {
      return true;
    }
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}
let arr = [];
console.log(myInstanceOf(arr, Array)); // true
console.log(myInstanceOf(arr, Object)); // true
console.log(myInstanceOf(arr, RegExp)); // false

该方法首先获取object的原型对象,并循环遍历原型链,逐级比较每个原型对象是否等于constructor.prototype。如果找到了相等的原型对象,则返回true,否则返回false

7.(0.1+0.2 ! == 0.3)问题

  • 原因

    使用 IEEE 754 标准来表示浮点数,该标准使用二进制来表示小数。因为在二进制中无法准确地表示一些十进制小数,因此在进行浮点数计算时会出现舍入误差,从而导致某些计算结果不准确。

    0.1 在十进制中可以准确地表示为 0.1,但在二进制中表示为 0.0001100110011001100110011001100110011001100110011...(循环节为 0011),其中小数点后的数值是无限循环的。同样地,0.2 在二进制中也是无限循环的,表示为 0.0011001100110011001100110011001100110011001100110...(循环节为 0011

  • 解决方案

    • 方案1:Math.abs()

      function isEqual(num1, num2) {
        return Math.abs(num1 - num2) < Number.EPSILON;
      }
      // Number.EPSILON 属性表示 1 与Number可表示的大于 1 的最小的浮点数之间的差值。
      console.log(isEqual(0.1 + 0.2, 0.3); // 输出 true
      
    • 方案2:toFixed()

      var result = (0.1 + 0.2).toFixed(1); // 将小数点后一位四舍五入
      console.log(result); // 输出 0.3
      

      注意:``toFixed()Chrome 浏览器中存在精度问题(工作中踩的坑😢),例如parseFloat((0.615).toFixed(2))的结果为0.61。具体可参考这篇文章点我跳转

8.类型转换

类型转换可以分为两种:

  • 隐式类型转换:JavaScript 引擎自动将一个数据类型转换为另一个数据类型,常见的隐式类型转换包括:

    • 字符串和数字之间的运算,会将字符串转换为数字。
    • 布尔值和数字之间的运算,会将布尔值转换为数字。
    • 字符串和布尔值之间的运算,会将字符串转换为布尔值。
    • 对象和原始值之间的运算,会将对象转换为原始值。
    • undefined 和 null 会被转换为 false,数字 0 也会被转换为 false。
  • 显式类型转换: 开发人员明确地将一个数据类型转换为另一个数据类型,常见的显式类型转换包括:

    • 使用 Number() 函数将字符串转换为数字。
    • 使用 parseInt() 函数将字符串转换为整数。
    • 使用 parseFloat() 函数将字符串转换为浮点数。
    • 使用String()函数将数字或其他数据类型转换为字符串。
    • 使用 Boolean() 函数将其他数据类型转换为布尔值。

9.Object.is()、==、===的区别

Object.is()“===”“==”都用于比较两个值是否相等。

  • Object.is() 方法

    一般情况下和===的判断结果相同,但是新增了特殊情况,比如:-0+0不相等,NaNNaN是相等的

  • ==操作符

    用于比较两个值是否相等,如果类型不一致会强制类型转化后再比较

  • ===操作符

    用于比较两个值是否严格相等,它会进行类型和值的比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值