数据类型
数据类型分2种,一种是基本类型,一种是引用类型。
基本类型:
- 值不可变
- 基本类型之间的比较是值比较
- 基本类型的变量存放在栈区
js不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,我们操作的实质上,是操作对象的引用,所以引用类型的值是按引用访问的。
引用类型:
- 值可动态变化
- 引用类型的比较是引用的比较,也就是比较堆内存中的地址是否相同
- 引用类型的值是同时保存在栈内存和堆内存中的对象 ,栈区内存保存变量标识符和指向内存中该对象的指针
赋值:
简单赋值:从一个变量给另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上。所以当被赋值变量的值发生变化时,是不会影响原赋值变量的。
引用赋值:从一个变量向另一个变量赋值引用类型时,也会复制一个值放到新变量的栈内存中,但我们知道引用类型存在栈内存中的是变量标示符和指向堆内存的指针,即原赋值变量跟被赋值变量均保存了同一个对象的地址,那么改变其中一个变量,将会影响另一个变量。所以,引用类型的赋值,其实是对象保存在栈区地址指针的赋值。
类型判断
首先明确需要判断的目标类型有哪些,可以用什么方法来判断。
当类型是基本类型时,使用 typeof 可以返回对应的类型,null 例外,如:
var str = 'hello'; // typeof str; "string"
var bool = false; // typeof bool; "string"
var num = 123; // typeof num; "number"
var undef; // typeof undef; "undefined"
var _null = null; // typeof _null; "object"
对于引用类型的变量,typeof 会返回 function 和 object 两种值。
function a() {}; // typeof a; "function"
var array = []; // typeof array; "object"
var obj = {}; // typeof array; "object"
可见,当类型是引用类型时,使用 typeof 来判断就显得力不从心了。
所以如果需要准确判断数据类型,就得祭出神器 -- Object.prototype.toString 。
调用 Object.prototype.toString 会返回 "[object " 和 class 和 "]" 三个部分组成的字符串。
var str = 'hello'; // Object.prototype.toString.call(str); "[object, String]"
var bool = false; // Object.prototype.toString.call(bool); "[object, Boolean]"
var num = 123; // Object.prototype.toString.call(num); "[object, Number]"
// ie6 中 null 和 undefined 返回 "[object, Object]",所以需要额外处理一下
var undef; // Object.prototype.toString.call(undef); "[object, Undefined]"
var _null = null; // Object.prototype.toString.call(_null); "[object, Null]"
var array = []; // Object.prototype.toString.call(array); "[object, Array]"
var obj = {}; // Object.prototype.toString.call(obj); "[object, Object]"
var date = new Date(); // Object.prototype.toString.call(date); "[object, Date]"
var func = function() {}; // Object.prototype.toString.call(func); "[object, Function]"
var error = new Error(); // Object.prototype.toString.call(error); "[object, Error]"
var reg = /a/g; // Object.prototype.toString.call(reg); "[object, RegExp]"
var math = Math; // Object.prototype.toString.call(math); "[object, Math]"
var json = JSON; // Object.prototype.toString.call(json); "[object, JSON]"
function a() {
console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
}
a();
参考 jquery 的类型判断 写法。
function _typeof(value) {
// undefined == null 是 true,所以 null 跟 undefined 将会直接返回
if (value == null) {
return value + "";
}
var class2type = {};
"String Number Boolean Object Function Array Date Error RegExp".split(" ").map(function(item, index) {
return class2type["[object" + item + "]"] = item.toLowerCase();
});
// || 'object' 是为了判断的 value 如果是 es6 中的Symbol, Map, Set等类型,将返回默认的 'object'
return typeof value === 'object' || typeof value === 'function' ?
class2type[Object.prototype.toString.call(value)] || 'object'
: typeof value;
}
还有其他类型,比如 PlainObject, EmptyObject, Window对象, isArrayLike, isElement等,请看 JavaScript专题之类型判断(下)
此外,关于数据方面的知识,还有:
感兴趣的看官老爷,不妨顺着链接去看看哦。