Manchan's blog Manchan's blog
首页
  • 前端文章

    • HTML5
    • CSS3
    • JavaScript
  • 学习笔记

    • CSS选择器世界
地信
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 旧版博客
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
友链
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

まん酱

一个正在学习中的GISer~
首页
  • 前端文章

    • HTML5
    • CSS3
    • JavaScript
  • 学习笔记

    • CSS选择器世界
地信
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 旧版博客
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
友链
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript

    • JavaScript参考手册
    • 33个非常实用的JavaScript一行代码
    • new命令原理
    • ES5面向对象
    • ES6面向对象
    • 多种数组去重性能对比
    • JS数据类型
      • JS 数据类型有哪些?
      • 数据类型检测的方式有哪些?
      • instanceof 能否判断基本数据类型?
    • JS随机打乱数组
    • 判断是否为移动端浏览器
    • 将一维数组按指定长度转为二维数组
    • 防抖与节流函数
    • JS获取和修改url参数
    • 比typeof运算符更准确的类型判断
  • 学习笔记

  • 前端
  • JavaScript
manchan
2023-06-15
目录

JS数据类型

# JS 数据类型有哪些?

JS 的数据类型分为两大类,一是原始类型,二是对象类型。原始类型存储的是值,一般存储在栈上,对象类型存储的是指针,一般存储在堆上。

# 原始类型

  • Boolean 类型

    Boolean 类型表示一个逻辑实体并且包括两个值:true 和 false。

  • Null 类型

    Null 类型只有一个值:null。表示没有任何对象。

    但是typeof null 会输出 object,所以不能通过typeof来判断null。

  • Undefined 类型

    Undefined 类型只有一个值:undefined。表示没有任何值。

    没有值(return;)的 return 语句,隐式返回 undefined。

    访问不存在的对象属性(obj.iDontExist),返回 undefined。

    变量声明时没有初始化(let x;),隐式初始化为 undefined。

    许多如 Array.prototype.find() 和 Map.prototype.get() 的方法,当没有发现元素时,返回 undefined。

  • Number 类型

    Number 类型是一种双精度 64 位二进制格式的值。

    NaN(“Not a Number”)是一个特殊种类的数值,当算术运算的结果不表示数值时,通常会遇到它。

  • BigInt 类型

    BigInt 类型在 Javascript 中是一个数字的原始值,它可以表示任意大小的整数。

  • String 类型

    String 类型表示文本数据并编码为 UTF-16 代码单位的 16 位无符号整数值序列。

  • Symbol 类型

    Symbol 是唯一并且不可变的原始值并且可以用来作为对象属性的键。

原始类型存储的都是值,是没有函数可以调用的。

# 对象类型

当创建了一个对象类型的时候,计算机会在堆内存中帮我们开辟一个空间来存放值,但是我们需要找到这个空间,这个空间会拥有一个地址(指针)。

# 数据类型检测的方式有哪些?

# typeof

console.log(typeof 2) // number
console.log(typeof true) // boolean
console.log(typeof 'str') // string
console.log(typeof []) // object
console.log(typeof function () {}) // function
console.log(typeof {}) // object
console.log(typeof undefined) // undefined
console.log(typeof null) // object
1
2
3
4
5
6
7
8

其中数组、对象、null 都会被判断为 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
1
2
3
4
5
6
7

instanceof 只能正确判断引用数据类型,而不能判断基本数据类型。instanceof 运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

# 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
1
2
3
4
5
6

constructor 有两个作用,一是判断数据的类型,二是对象实例通过 constrcutor 对象访问它的构造函数。需要注意,如果创建一个对象来改变它的原型,constructor 就不能用来判断数据类型了:

function Fn() {}

Fn.prototype = new Array()

var f = new Fn()

console.log(f.constructor === Fn) // false
console.log(f.constructor === Array) // true
1
2
3
4
5
6
7
8

# Object.prototype.toString.call()

Object.prototype.toString.call() 使用 Object 对象的原型方法 toString 来判断数据类型:

var a = Object.prototype.toString

console.log(a.call(2)) //[object Number]
console.log(a.call(true)) //[object Boolean]
console.log(a.call('str')) //[object String]
console.log(a.call([])) //[object Array]
console.log(a.call(function () {})) //[object Function]
console.log(a.call({})) //[object Object]
console.log(a.call(undefined)) //[object Undefined]
console.log(a.call(null)) //[object Null]
1
2
3
4
5
6
7
8
9
10

同样是检测对象 obj 调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?

这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。

不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array 类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将 obj 转换为字符串类型。

因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

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

对于原始类型来说,想直接通过 instanceof 来判断类型是不行的,但是我们还是有办法实现的,比如下面这种方式:

class PrimitiveNumber {
  static [Symbol.hasInstance](x) {
    return typeof x === 'number'
  }
}
console.log(111 instanceof PrimitiveNumber) // true
1
2
3
4
5
6

Symbol.hasInstance 用于判断某对象是否为某构造器的实例。因此你可以用它自定义 instanceof 操作符在某个类上的行为。

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

微信 支付宝
文章更新于: 2023/06/15 17:15:17
多种数组去重性能对比
JS随机打乱数组

← 多种数组去重性能对比 JS随机打乱数组→

最近更新
01
Git移动&重命名
06-15
02
利用宇宙最牛人工智能ChatGPT,帮你爬取百度POI,并处理成CSV
03-12
03
在线文档
02-03
更多文章>
Theme by Vdoing | Copyright © 2020-2023 Manchan All rights reserved.
鄂ICP备2020015911-1号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式