基础系列-JS数据类型

基本数据类型

指简单的数据段。基本数据类型存储在栈内存中。

不能给基础数据类型添加属性。

  • 存储原始数据类型
  • 按值访问
  • 存储的值大小固定
  • 由系统自动分配内存空间
  • 空间小,运行效率高
  • 先进后出,后进先出

String

Number

Boolean

Null

Undefined

Symbol

BigInt

引用数据类型

指可能由多个值构成的对象。引用数据类型存储在堆内存中。

js 不能直接操作对象的内存空间。实际上是在操作对象的引用而不是实际的对象。

  • 存储引用数据类型
  • 按引用地址访问
  • 存储的值大小不定,可动态调整
  • 由代码进行指定分配
  • 空间大,运行效率相对较低
  • 无序存储,可根据引用直接获取

Object

null 为特殊引用类型,指针指向空地址。

function 是特殊的object,特殊引用类型,但不用于存储数据,所以没有“拷贝、复制”一说。

类型判断

typeof

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

typeof 'a' // 'string'
typeof 123 // 'number'
typeof true // 'boolean'
typeof [] // 'object'
typeof {} // 'object'
typeof null // 'object'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof Object.prototype.toString // 'function'
typeof /1232/ // 'object'

instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

'abc' instanceof String // false
123 instanceof Number // false
123 instanceof Number // false

true instanceof Boolean // false
Boolean(true) instanceof Boolean // false
new Boolean() instanceof Boolean // true
new Boolean() instanceof Object // true

null instanceof Object // false
Symbol() instanceof Symbol // false
[] instanceof Object // true
[] instanceof Array // true
Object.prototype.toString instanceof Function // true
/1232/ instanceof RegExp // true
/1232/ instanceof Obejct // true

注意对象包装器问题,String()Boolean()Number()等对象包装器,如果使用new进行构建,得到的是对象。

var a = new Boolean(false); 
console.log(!a) // false, 此时的a是对象 对象本身是truthy

参考链接:《你不懂JS:类型与文法》第三章:原生类型

Object.prototype.toString() 原型链的方式

每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 “[object type]”,其中 type 是对象的类型。以下代码说明了这一点:

var o = new Object();
o.toString(); // '[object Object]'

可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg

var toString = Object.prototype.toString;

toString.call(new String); // '[object String]'
toString.call(''); // '[object String]'
toString.call(new Number); // '[object Number]'
toString.call(123); // '[object Number]'
toString.call(new Boolean); // '[object Boolean]'
toString.call(true); // '[object Boolean]'
toString.call([]); // '[object Array]'
toString.call({}); // '[object Object]'
toString.call(function() {}); // '[object Function]' 
toString.call(Math); // '[object Math]'
toString.call(new Date); // '[object Date]'

//Since JavaScript 1.8.5
toString.call(undefined); // '[object Undefined]'
toString.call(null); // '[object Null]'

function fn() {
    return Object.prototype.toString.call(arguments)
}
console.log(fn()) // '[object Arguments]'

Arguments类数组

function fn() {
    console.log(typeof arguments) // 'object'
    console.log(arguments instanceof Object) // true
    console.log(arguments instanceof Array) // false
    console.log(Object.prototype.toString.call(arguments)) // '[object Arguments]'
}
fn()

Symbol.toStringTag 可以定制’[object tag]’中的tag值

对象的Symbol.toStringTag属性,指向一个方法。在该对象上面调用Object.prototype.toString方法时,如果这个属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object][object Array]object后面的那个字符串。

参考链接:https://es6.ruanyifeng.com/#docs/symbol

学习链接

谈谈 Object.prototype.toString – 掘金