We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在最新的 ECMAScript规范 中,一共定义了 7 种数据类型,
基本类型是存储在 栈(Stack) 中的简单数据段,引用类型的值是存储在 堆(Heap) 中的对象。
数据类型的值存储在堆中还是栈中,取决于值的特性。基本类型占据的空间固定,存储在栈中按值访问,可以提升变量的查询速度。引用类型的值大小不固定,不适合存储在栈中,JavaScript中采取的做法是,将引用类型的值存储在堆中,同时在栈中存储值的访问地址,所以引用类型是 按地址访问 的。
var arr = [1, 2, 3] // 引用类型的值其实就是存储在堆内存中的对象,访问方式为按地址访问,首先找到栈区中值的地址,然后沿着地址找到堆内存中对应的对象。
对于数据类型的判断,JavaScript 也提供了很多种方法,遗憾的是,不同的方法得到的结果参差不齐,下面列出了我所知道的所有的类型判断方法,如果有遗漏,欢迎在评论区补充。
JavaScript
typeof 返回未经计算的操作数的类型的字符串,可能会有一些意料之外的结果:
typeof
typeof null === 'object' // true, 从一开始出现 JavaScript 就是这样的 typeof NaN === 'number' // true, 尽管 NaN 是 Not-A-Number 的缩写,typeof 还是会返回 number typeof [] === 'object' // true, 引用类型除了 function 外,都返回 object typeof Infinity === 'number' // true typeof function() {} === 'function' // true
typeof 能够判断大多数类型,总结 typeof 的运算规则就是:
instanceof 用来判断 A 是否是 B 的实例,所以 instanceof 可以正确地判断对象的类型,因为其内部的实现机制是通过判断对象的原型链中是否能找到类型的 prototype。
instanceof
prototype
[] instanceof Array // true [].__proto__ === Array.prototype // true
也正是因为 instanceof 的实现本质上是基于原型链的查找,所以也会出现意料之外的情况:
[] instanceof Object // true [].__proto__.__proto__ === Object.prototype // true
此外,instanceof 操作符的语法是 object instanceof constructor,要求操作符的左右两侧都必须是对象,所以无法判断 null, undefined 等类型。
object instanceof constructor
null
undefined
我们知道当创建一个函数 F 时,JavaScript 引擎会为 F 添加 prototype 属性,然后在 prototype 属性上添加一个 constructor 属性,让它指向 F 的引用:
constructor
function F() {} F.prototype.constructor === F // true
这是引擎默认的行为,目的是表明对象是由那个函数构造的,在 JavaScript 中,function 其实就是一个语法糖,所有的函数本质上都是一个 Function 对象。利用这一特性,我们可以通过 constructor 来判断对象的数据类型,因为 JavaScript 为我们提供了很多的内置对象:
function
Function
[].constructor === Array // true ''.constructor === String // true false.constructor === Boolean // true new Number().constructor === Number // true
但是 constructor判断类型是 “不可靠的”,因为 constructor 属性可以被修改,比如:
var a = 1 a.constructor === Number // true a.__proto__.constructor = String a.constructor === Number // false a.constructor === String // true
constructor 也不能用来判断 null 和 undefined,因为他们都不是对象。
Object 原型上的方法 toString 返回一个表示该对象的字符串 [object Xxx]。
Object
toString
[object Xxx]
ECMAScript 5 和随后的 Errata 中定义,从 JavaScript 1.8.5 开始,toString() 调用 null 返回 [object Null],undefined 返回 [object Undefined]。对于 Object 对象,直接调用 toString 就可以获得类型字符串,其他类型,需要借助 Object.prototype.toString.call/apply 来返回正确的类型值。至此,toString 成为判断数据类型最完备的一种方法:
ECMAScript 5
Errata
JavaScript 1.8.5
toString()
[object Null]
[object Undefined]
Object.prototype.toString.call/apply
Object.prototype.toString.call('') // [object String] Object.prototype.toString.call(/([A-Z])\w+/g) // [object RegExp] Object.prototype.toString.call(null) // [object Null] Object.prototype.toString.call(undefined) // [object Undefined] Object.prototype.toString.call(NaN) // [object Number]
我们只需要对 toString 稍加封装就可以实现 JavaScript 中所有类型的判断,举个例子:
function getType(obj) { const typeClass = Object.prototype.toString.call(obj) const classMatch = { '[object String]': 'string', '[object Number]': 'number', '[object Boolean]': 'boolean', '[object Symbol]': 'symbol', '[object Object]': 'object', '[object Array]': 'array', '[object Function]': 'function', '[object RegExp]': 'regexp', '[object Date]': 'date', '[object Error]': 'error', '[object Window]': 'window', '[object HTMLDocument]': 'document' } if (obj == null) { // 如果是 null 或 undefined ,调用 toString 后返回 return obj + '' } else { // 如果是 object 和 function ,调用 Object.prototype.toString 匹配具体的类型,其余情况直接调用 typeof return (typeof obj === 'object' || typeof obj === 'function') ? classMatch[typeClass] : typeof obj } }
如果有疑问或者发现错误,可以在相应的 issues 进行提问或勘误
如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励
(完)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
在最新的 ECMAScript规范 中,一共定义了 7 种数据类型,
基本类型是存储在 栈(Stack) 中的简单数据段,引用类型的值是存储在 堆(Heap) 中的对象。
数据类型的值存储在堆中还是栈中,取决于值的特性。基本类型占据的空间固定,存储在栈中按值访问,可以提升变量的查询速度。引用类型的值大小不固定,不适合存储在栈中,JavaScript中采取的做法是,将引用类型的值存储在堆中,同时在栈中存储值的访问地址,所以引用类型是 按地址访问 的。
对于数据类型的判断,
JavaScript
也提供了很多种方法,遗憾的是,不同的方法得到的结果参差不齐,下面列出了我所知道的所有的类型判断方法,如果有遗漏,欢迎在评论区补充。typeof
typeof
返回未经计算的操作数的类型的字符串,可能会有一些意料之外的结果:typeof
能够判断大多数类型,总结typeof
的运算规则就是:instanceof
instanceof
用来判断 A 是否是 B 的实例,所以instanceof
可以正确地判断对象的类型,因为其内部的实现机制是通过判断对象的原型链中是否能找到类型的prototype
。也正是因为
instanceof
的实现本质上是基于原型链的查找,所以也会出现意料之外的情况:此外,
instanceof
操作符的语法是object instanceof constructor
,要求操作符的左右两侧都必须是对象,所以无法判断null
,undefined
等类型。constructor
我们知道当创建一个函数 F 时,
JavaScript
引擎会为 F 添加prototype
属性,然后在prototype
属性上添加一个constructor
属性,让它指向 F 的引用:这是引擎默认的行为,目的是表明对象是由那个函数构造的,在
JavaScript
中,function
其实就是一个语法糖,所有的函数本质上都是一个Function
对象。利用这一特性,我们可以通过constructor
来判断对象的数据类型,因为JavaScript
为我们提供了很多的内置对象:但是
constructor
判断类型是 “不可靠的”,因为constructor
属性可以被修改,比如:constructor
也不能用来判断null
和undefined
,因为他们都不是对象。Object.prototype.toString.call
Object
原型上的方法toString
返回一个表示该对象的字符串[object Xxx]
。ECMAScript 5
和随后的Errata
中定义,从JavaScript 1.8.5
开始,toString()
调用null
返回[object Null]
,undefined
返回[object Undefined]
。对于Object
对象,直接调用toString
就可以获得类型字符串,其他类型,需要借助Object.prototype.toString.call/apply
来返回正确的类型值。至此,toString
成为判断数据类型最完备的一种方法:我们只需要对
toString
稍加封装就可以实现JavaScript
中所有类型的判断,举个例子:勘误与提问
如果有疑问或者发现错误,可以在相应的 issues 进行提问或勘误
如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励
(完)
The text was updated successfully, but these errors were encountered: