神族九帝's blog 神族九帝's blog
首页
网盘 (opens new window)
线报 (opens new window)
商城 (opens new window)
  • 复习指导
  • HTML
  • CSS
  • JavaScript
  • 设计模式
  • 浏览器
  • 手写系列
  • Vue
  • Webpack
  • Http
  • 前端优化
  • 项目
  • 面试真题
  • 算法
  • 精选文章
  • 八股文
  • 前端工程化
  • 基础篇
  • 进阶篇
  • 高级篇
  • 计算机基础
  • 高频考点
  • 精简题
  • 综合问题
  • 复习题
  • vue
  • vue2源码学习
  • 剖析vuejs内部运行机制
  • TypeScript 入门实战笔记
  • vue3源码学习
  • 2周刷完100道前端优质面试真题
  • npm发包
  • 重学node
  • 前端性能优化方法与实战
  • webpack原理与实战
  • webGl
  • 前端优化
  • Web3
  • 更多
  • 网站
  • 资源
  • Vue资源
  • 收藏的一些API
  • 未来要做的事
  • 宝塔面板+青龙面板
  • 安卓手机当服务器使用
  • 京东自动评价代码
  • 搭建x-ui免流服务器(已失效)
  • 海外联盟
  • 好玩的docker
  • 导航
GitHub (opens new window)

神族九帝,永不言弃

首页
网盘 (opens new window)
线报 (opens new window)
商城 (opens new window)
  • 复习指导
  • HTML
  • CSS
  • JavaScript
  • 设计模式
  • 浏览器
  • 手写系列
  • Vue
  • Webpack
  • Http
  • 前端优化
  • 项目
  • 面试真题
  • 算法
  • 精选文章
  • 八股文
  • 前端工程化
  • 基础篇
  • 进阶篇
  • 高级篇
  • 计算机基础
  • 高频考点
  • 精简题
  • 综合问题
  • 复习题
  • vue
  • vue2源码学习
  • 剖析vuejs内部运行机制
  • TypeScript 入门实战笔记
  • vue3源码学习
  • 2周刷完100道前端优质面试真题
  • npm发包
  • 重学node
  • 前端性能优化方法与实战
  • webpack原理与实战
  • webGl
  • 前端优化
  • Web3
  • 更多
  • 网站
  • 资源
  • Vue资源
  • 收藏的一些API
  • 未来要做的事
  • 宝塔面板+青龙面板
  • 安卓手机当服务器使用
  • 京东自动评价代码
  • 搭建x-ui免流服务器(已失效)
  • 海外联盟
  • 好玩的docker
  • 导航
GitHub (opens new window)
  • 复习指导

  • HTML

  • CSS

  • JavaScript

    • 思维导图
    • 数据类型
      • js 原始数据类型?引用数据类型?
        • 原始值
        • 引用数据类型
      • null 是对象么
      • 0.1+0.2 为什么不等于 0.3
      • typeof
      • instanceof 能否判断基本数据类型
      • 实现 instanceof 功能
      • Object.is 和 ===
      • [] !== []
      • js 类型转换哪几种?
      • == 和 ===
      • 对象转原始类型流程
      • 如何让 if( a === 1 && a === 2)成立
      • iframe 特殊处理
      • 参考链接
    • 隐式类型转换
    • 闭包
    • 原型和原型链
    • 继承
    • 数组扁平化flat
    • new操作符做了什么
    • 数组去重性能
    • 防抖与节流函数
    • 深浅拷贝
    • Event Loop
    • 数组方法和类数组
    • 数组排序
    • 异步编程
    • 获取URL参数
    • 模块规范
    • tree-shaking的原理
    • 隔离沙箱
  • 设计模式

  • 浏览器

  • 手写系列

  • Vue

  • Webpack

  • Http

  • 前端优化

  • 项目

  • 面试真题

  • 算法

  • 精选文章

  • 八股文

  • 前端工程化

  • 面试题
  • JavaScript
wu529778790
2018-06-15

数据类型

Object.prototype.toString
  .call()
  .match(/\[object (.*?)\]/)[1]
  .toLowerCase();

# js 原始数据类型?引用数据类型?

# 原始值

  • undefined
  • null
  • string
  • number
  • boolean
  • symbol
  • bigInt

# 引用数据类型

对象 Object

  • 普通对象 Object
  • 正则对象 RegExp
  • 函数对象 function
  • 数组对象 Array
  • 日起对象 Date
  • 数学函数 Math

# null 是对象么

不是对象

虽然 typeof null 会输出 object,但是这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object 。

# 0.1+0.2 为什么不等于 0.3

0.1 和 0.2 在转换成二进制后会无限循环,由于标准位数的限制后面多余的位数会被截掉,此时就已经出现了精度的损失,相加后因浮点数小数位的限制而截断的二进制数字在转换为十进制就会变成 0.30000000000000004

# typeof

对于原始类型来说,除了 null 都可以调用 typeof 显示正确的类型

但对于引用数据类型,除了函数之外,都会显示"object"。

因此采用 typeof 判断对象数据类型是不合适的,采用 instanceof 会更好,instanceof 的原理是基于原型链的查询,只要处于原型链中,判断永远为 true

# instanceof 能否判断基本数据类型

能,但是要改写

其实就是自定义 instanceof 行为的一种方式,这里将原有的 instanceof 方法重定义,换成了 typeof,因此能够判断基本数据类型

class PrimitiveNumber {
  static [Symbol.hasInstance](x) {
    return typeof x === "number";
  }
}
console.log(111 instanceof PrimitiveNumber); // true

# 实现 instanceof 功能

原型链的向上查找

function myInstanceof(left, right) {
  //基本数据类型直接返回false
  if (typeof left !== "object" || left === null) return false;
  //getProtypeOf是Object对象自带的一个方法,能够拿到参数的原型对象
  let proto = Object.getPrototypeOf(left);
  while (true) {
    //查找到尽头,还没找到
    if (proto == null) return false;
    //找到相同的原型对象
    if (proto == right.prototype) return true;
    proto = Object.getPrototypeof(proto);
  }
}

# Object.is 和 ===

Object 在严格等于的基础上修复了一些特殊情况下的失误,具体来说就是+0 和-0,NaN 和 NaN

function is(x, y) {
  if (x === y) {
    //运行到1/x === 1/y的时候x和y都为0,但是1/+0 = +Infinity, 1/-0 = -Infinity, 是不一样的
    return x !== 0 || y !== 0 || 1 / x === 1 / y;
  } else {
    //NaN===NaN是false,这是不对的,我们在这里做一个拦截,x !== x,那么一定是 NaN, y 同理
    //两个都是NaN的时候返回true
    return x !== x && y !== y;
  }
}

# [] !== []

== 中,左右两边都需要转换为数字然后进行比较。

[]转换为数字为 0。

![] 首先是转换为布尔值,由于[]作为一个引用类型转换为布尔值为 true, 因此![]为 false,进而在转换成数字,变为 0。

0 == 0 , 结果为 true

# js 类型转换哪几种?

  • 转换成数字
  • 转换成布尔值
  • 转换成字符串

20210615173058

# == 和 ===

===叫做严格相等,是指:左右两边不仅值要相等,类型也要相等

==不像===那样严格,对于一般情况,只要值相等,就返回 true,但==还涉及一些类型转换

转换规则:

  • 两边的类型是否相同,相同的话就比较值的大小
  • 判断是否是 null 和 undefined,是的话就返回 true
  • 判断是否是 String 和 Number,是的话,把 String 类型转换成 Number,再进行比较
  • 判断其中一方是否是 Boolean,是的话就把 Boolean 转换成 Number,再进行比较
  • 如果其中一方为 Object,且另一方为 String、Number 或者 Symbol,会将 Object 转换成字符串,再进行比较
console.log({ a: 1 } == true); //false
console.log({ a: 1 } == "[object Object]"); //true

# 对象转原始类型流程

对象转原始类型,会调用内置的[ToPrimitive]函数,对于该函数而言,其逻辑如下

  1. 如果 Symbol.toPrimitive()方法,优先调用再返回
  2. 调用 valueOf(),如果转换为原始类型,则返回
  3. 调用 toString(),如果转换为原始类型,则返回
  4. 如果都没有返回原始类型,会报错

并非所有对象的隐式转换都会按照 Symbol.toPrimitive()->valueOf()->toString()这个顺序尝试,Date 对象会优先尝试 toString()方法来实现转换,非 Date 对象按照上述顺序

var obj = {
  value: 3,
  valueOf() {
    return 4;
  },
  toString() {
    return "5";
  },
  [Symbol.toPrimitive]() {
    return 6;
  },
};
console.log(obj + 1); // 输出7

# 如何让 if( a === 1 && a === 2)成立

var a = {
  value: 0,
  valueOf: function() {
    this.value++;
    return this.value;
  },
};
console.log(a == 1 && a == 2); //true

还有一个 sao 断腿的解法:

var a = [1, 2];
a.join = a.shift;
console.log(a == 1 && a == 2);

# iframe 特殊处理

5ee7d14415ec33b5c8cdc3d32b72731

instanceof 不能检测出基本类型,而且不能跨 iframe 1626945913(1)

其实就是两套隔离的进程,无法通信

20210722171805

# 参考链接

  • https://sanyuan0704.top/my_blog/blogs/javascript/js-base/001.html (opens new window)
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof (opens new window)
编辑 (opens new window)
上次更新: 2022/05/24, 14:27:28
思维导图
隐式类型转换

← 思维导图 隐式类型转换→

最近更新
01
好玩的docker
07-04
02
我的第一个NFT
07-03
03
海外迅雷
06-01
更多文章>
Power by vuepress | Copyright © 2015-2023 神族九帝
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×