前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript 数据类型

JavaScript 数据类型

作者头像
李振
发布2021-11-26 14:42:12
2650
发布2021-11-26 14:42:12
举报
文章被收录于专栏:乱码李

JavaScript 语言可以识别 7 中不同的数据类型,除 Object 外,其它均为基本数据类型,Object 为引用数据类型。

  • Undefined, 只有一个值,即特殊值 undefined,使用 var/let/const 声明但未初始化的值。
  • Null,只有一个值,即特殊值 null,null 值表示一个空对象指针。
  • Boolean,布尔型,true 和 false。
  • Number, 整数和浮点数。
  • String, 字符串,由零个或者多个 16 位 Unicode 字符串组成的字符序列。
  • Symbol, ES6 新增类型,它的实例是唯一且不可改变的。
  • Object, 一组数据和功能的集合。可以通过 new 加对象名称创建。

Undefined 类型

代码语言:javascript
复制
var message // 变量声明之后默认取得了 undefined 值
message == undefined // true
message === undefined // true

Null 类型

Null 类型只有一个值 null,null 表示一个空指针对象。

代码语言:javascript
复制
typeof null // "objec"

如果定义变量准备在将来保存对象,最好讲该变量初始化为 null,这样可以通过检查 null 来判断是否已经保存了一个对象的引用。

实际上,undefined 值派生自 null

代码语言:javascript
复制
null == undefined // true
null === undefined // false

null vs undefined

尽管 null 和 undefined 之间的相等操作符(==)返回 true,不过它们的用途完全不同,如前所述,无论什么情况下,没有必要把一个变量的值设为 undefined,而如果一个变量将来要保存对象,应该将其显式地设为 null。

Boolean 类型

对于任何数据类型,调用 Boolean() 函数,总是会返回一个 Boolean 值。

代码语言:javascript
复制
Boolean(0) // false
Boolean(NaN) // false
Boolean(null) // false
Boolean(undefined) // false
Boolean('/t') // false

Number 类型

(1) 整数:

代码语言:javascript
复制
var intNum = 55
var octalNum = 070 // 八进制的 56
var hexNum = 0xA // 十六进制的 10

+0 === -0 // true

(2) 浮点数:

代码语言:javascript
复制
3e-17 // 0.000...03

0.1 + 0.2 // 0.30000000000000004 浮点数最高精度为 17 位小数
0.1 + 0.2 === 0.3 // false

ECMAScript 最小数:Number.MIN_VALUE,在大多数浏览器中为 5e-324。 ECMAScript 最大数:Number.MAX_VALUE,在大多数浏览器中为 1.7976931348623157e+308。

如果计算超过 JavaScript 数值范围,会自动转为特殊的 Infinity 值,负数则为 -Infinity。Infinity 不能参与数值计算。通过 isFinite() 函数判断参数是否位于最大值和最小值之间。

代码语言:javascript
复制
1 / 0 // Infinity
isFinite(Number.MAX_VALUE + Number.MAX_VALUE) // false

(3) NaN (Not a Number)

NaN 用来表示本来要返回数值的操作数未返回数值的情况,避免抛出错误。

NaN 的设计有两个特点:

1.任何涉及 NaN 的操作都返回 NaN 2.NaN与任何值都不相等,包括 NaN 本身

代码语言:javascript
复制
0/0 // NaN
NaN/10 // NaN
NaN == NaN // false

针对这两个特点,ECMAScript 设计了 isNaN() 函数。这个函数帮助我们判断参数是否 “不是数值”。isNaN() 接受参数后,会尝试将这个值转换为数值,如果这个值不能被转换为数值,则返回 true。

代码语言:javascript
复制
isNaN(NaN) // true
isNaN(10) // false
isNaN('10') // false 可以转换为数值 10
isNaN('blue') // true 不能转换为数值
isNaN(true) // false 可以转换为数值 1

(4) 数值转换

Number() 函数转换规则如下:

1.如果是 Boolean 值,返回 1 或者 0。 2.数字直接返回。 3.null 返回 0。 4.undefined 返回 NaN。 5.字符串:如果是十进制整数,八进制整数或者十六进制整数返回十进制整数,空字符串返回 0,其它均返回 NaN。 6.如果是对象,调用对象的 valueOf() 方法,然后按照前面的转换规则转换,如果转换值为 NaN,则调用对象的 toString() 方法。

parseInt()

代码语言:javascript
复制
parseInt('1234blue') // 1234
parseInt('') // NaN
parseInt('0xA') // 10
parseInt(22.5) // 22
parseInt(070) // 56

parseInt() 解析八进制字面量的字符串时,ES3 和 ES5 存在区别,在 ES3 中 ‘070’ 被当做八进制字面量,ES5 则当做 ‘70’。 因此 parseInt 可以接收第二个参数,表示以多少进制解析第一个参数。

代码语言:javascript
复制
parseInt('0xAF', 16) // 175
parseInt('070') // 70
parseInt('070', 8) // 56

Symbol 类型

Symbol 是 ES6 新增的数据类型,用来解决对象中属性名重复的问题,Symbol 表示独一无二的值,通过 Symbol 函数生成。

代码语言:javascript
复制
Symbol("foo") !== Symbol("foo") // true
const foo = Symbol()
const bar = Symbol()
typeof foo === "symbol" // true
typeof bar === "symbol" // true
let obj = {}
obj[foo] = "foo"
obj[bar] = "bar"
JSON.stringify(obj) // {}
Object.keys(obj) // []
Object.getOwnPropertyNames(obj) // []
Object.getOwnPropertySymbols(obj) // [ foo, bar ]

Object 类型

Object 对象是一组数据和功能的集合。

代码语言:javascript
复制
var o = new Object()
var o = new Object

关于 Object 对象的详细内容,可以参考 深入学习JavaScript——Object对象使用 Object.defineProperty 为对象定义属性

如何判断数据类型

(1) typeof 操作符

typeof 操作符返回值一共有7种:number,boolean,symbol,string,object,undefined,function。

代码语言:javascript
复制
typeof '' // string 有效
typeof 1 // number 有效
typeof Symbol() // symbol 有效
typeof true //boolean 有效
typeof undefined //undefined 有效
typeof null //object 无效
typeof [] //object 无效
typeof new Function() // function 有效
typeof new Date() //object 无效
typeof new RegExp() //object 无效
  • 对于基本类型,除 null 以外,均可以返回正确的结果。
  • 对于引用类型,除 function 以外,一律返回 object 类型。
  • 对于 null ,返回 object 类型。
  • 对于 function 返回 function 类型。

(2) instanceof

instanceof 用来判断 A 是否为 B 的实例,需要注意的是,instanceof 检测的是原型。

可以理解为:

代码语言:javascript
复制
instanceof (A, B) {
  var L = A.__proto__
  var R = B.prototype
  return L === R    
}
代码语言:javascript
复制
[] instanceof Array // true
{} instanceof Object // true
new Date() instanceof Date // true

function A () {}
new A() instanceof A // true

[] instanceof Object // true
new Date() instanceof Object // true
new A() instanceof Object // true

[] 的 __proto__ 指向了 Array.prototype,而 Array.prototype.__proto__ 又指向了 Object.prototype,而 Object.prototype.__proto__ 指向了 null,因此 []、Array、Object 在内部形成了一条原型链。instanceof 只能用来判断两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型。

(3) constructor

当一个函数 F 被定义的时候,JS 引擎会自动帮其添加 prototype,并在 prototype 上添加一个 constructor 属性,并让其指向 F 的引用。

js_constructor
js_constructor

当实例化 F 的时候,var f = new F(),F 原型上的 constructor 传递到了 f 上,因此 f.constructor === F

F 利用原型对象上的 constructor 引用了自身,当 F 作为构造函数来创建对象时,原型上的 constructor 就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 F 就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型。

代码语言:javascript
复制
''.constructor === String
(1).constructor === Number
new Number(1).constructor === Number
new Function().constructor === Function
new Date().constructor === Date
new Error().constructor === Error
[].constructor === Array
document.constructor === HTMLDocument
window.constructor === Window

利用 constructor 判断数据类型存在的问题:

  1. null 和 undefined 是无效对象,因此没有 constructor 存在。
  2. 函数的 constructor 可以被重写,因此可能会出现判断错误。

(4) toString

toString() 是 Object 的原型方式,调用该方法,默认返回当前对象的 [[CLass]],其格式为 [object Xxx],其中 Xxx 就是对象的类型。

代码语言:javascript
复制
Object.prototype.toString.call('') // [object String]
Object.prototype.toString.call(1) // [object Number]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(Symbol()) //[object Symbol]
Object.prototype.toString.call(undefined) // [object Undefined]
Object.prototype.toString.call(null) // [object Null]
Object.prototype.toString.call(new Function()) // [object Function]
Object.prototype.toString.call(new Date()) // [object Date]
Object.prototype.toString.call([]) // [object Array]
Object.prototype.toString.call(new RegExp()) // [object RegExp]
Object.prototype.toString.call(new Error()) // [object Error]
Object.prototype.toString.call(document) // [object HTMLDocument]
Object.prototype.toString.call(window) // [object Window]

引用数据类型 vs 基本数据类型

基本数据类型复制相当于在内存中新开辟一块内存,引用数据类型的复制相当于在内存中创建了一个新的指针,指向存储在堆中的一个对象。

ECMAScript 中所有的函数都是 按值传递参数 的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另外一个变量一样。 在向参数传递基本数据类型的值时,被传递的值会被复制给一个局部变量(即命名参数,也就是 arguments 对象中的一个元素)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数外部。

代码语言:javascript
复制
function setName (obj) {
  obj.name = 'Leo'
}
var person = new Object()
setName(person)
console.log(person.name) // "Leo"

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-12-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Undefined 类型
  • Null 类型
  • Boolean 类型
  • Number 类型
  • Symbol 类型
  • Object 类型
  • 如何判断数据类型
  • 引用数据类型 vs 基本数据类型
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档