1、JS的基本数据类型有:
- undefined
- null
- number
- string
- Boolean
- Symbol
复杂数据类型有:
Object
2、null不是对象
从逻辑上看,null值表示一个空对象指针,这就是为什么使用typeof操作符检测null值时会返回object的原因,也是JavaScript遗留下来的bug。
而真正的原因是:JS类型值是存在32bit 单元里,为了性能考虑用低位储存了变量的类型信息,其中000表示是Object类型,而null对应机器码的NULL指针,一般全为零,所以typeof(null)为Object。要想正确判断数据的类型,不妨使用instanceof,因为instanceof的内部机制是通过原型链来判断的。
typeof
typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:
number
boolean
string
function(函数)
object(NULL,数组,对象)
undefined
instanceof
instanceof用于判断一个变量是否是某个对象的实例
语法:obj instanceof Object
function checkInstanceof() {
for (var i = 0; i < arguments.length; i++) {
console.log(Object.prototype.toString.call(arguments[i]))
}
}
checkInstanceof instanceof Function; //true
var obj ={ a:2 };
obj instanceof Object; //true
null instanceof Object; //false
var s =Symbol();
s instanceof Symbol//false 因为Symbol()不是对象类型
typeof s //"symbol"
Object.prototype.toString.call(s);// "[object Symbol]"
但有的时候instanceof也不一定百分百可信。因为我们可以使用Symbol.hasInstance来自定义instanceof的行为。
往下再多讲一下Object.prototype.toString.call():
Object.prototype.toString.call()
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a(){}; // [object Function]
function checkType() {
for (var i = 0; i < arguments.length; i++) {
console.log(Object.prototype.toString.call(arguments[i]))
}
}
checkType(number, string, boolean, und, nul, obj, array, date, error, reg, func)
console.log(Object.prototype.toString.call(Math)); // [object Math]
console.log(Object.prototype.toString.call(JSON)); // [object JSON]
3、基本数据类型和复杂数据类型有什么区别?
-
内存的分配不同
基本数据类型存储于栈中;
复杂数据类型存储在堆中,栈中存放指向堆中的地址。
-
值的结构不同
基本数据类型值指的是简单的数据段。
复杂的数据类型值是由一个或多个值构成的对象。
-
复制变量时不同
基本数据类型拷贝时,拷贝的是值,并且原变量和拷贝后的变量是相互独立的,这两个变量可以参与任何操作而不会相互影响;
复杂数据类型拷贝时,也就是所说的引用类型的值拷贝时,副本拷贝的是指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上引用的是同一个对象,因此,改变其中一个变量,就会影响另一个变量。
-
传递参数时不同
道理和拷贝一样。
在向参数传递基本类型的值时,被传递的值会被赋值给一个arguments对象中的一个元素(即局部变量);
在向参数传递引用类型的值时,会把对应值的地址复制给一个局部变量,因此局部变量的变化会反映到函数的外部。