数据类型
- 6种原始类型:
- boolean
- number
- string
- null
- undefined
- Symbol (ECMAScript 6 新定义)
- 一种引用类型 Object
- Array
- Object
- Function
- Date
- RegExp
- Error
- Arguments
我们通常用来检测数据类型的方法,分别是typeof
,Object.prototype.toString
,instanceof
typeof
var und=undefined;
var nul=null;
var boo=true;
var num=1;
var str='xys'
var obj=new Object();
var arr=[1,2,3];
var fun=function(){}
var date=new Date();
var reg = /a/g;
var err=new Error()
var arg;
(function getArg(){
arg=arguments;
})();
var symbol1 = Symbol();
console.log(typeof und); // undefined
console.log(typeof nul); // object
console.log(typeof boo); // boolean
console.log(typeof num); // number
console.log(typeof str); // string
console.log(typeof obj); // object
console.log(typeof arr); // object
console.log(typeof fun); // function
console.log(typeof date); // object
console.log(typeof reg); // object
console.log(typeof err); // object
console.log(typeof arg); // object
console.log(typeof symbol1); // symbol
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
可以看到,使用 typeof 方法来检测数据类型,基本类型大部分都能被准确检测并返回正确的字符串(除了 Null 类型,其返回 object 字符串),而引用类型大部分都不能够被准确检测(除了 Function 类型能够准确返回 function 字符串外,其它的都返回了 object 字符串)
Object.prototype.toString
Object.prototype.toString 最终会返回形式如 [object,class] 的字符串,class 指代的是其检测出的数据类型,这个是我们判断数据类型的关键
var toString=Object.prototype.toString;
console.log(toString.call(und)); // [object Undefined]
console.log(toString.call(nul)); // [object Null]
console.log(toString.call(boo)); // [object Boolean]
console.log(toString.call(num)); // [object Number]
console.log(toString.call(str)); // [object String]
console.log(toString.call(obj)); // [object Object]
console.log(toString.call(arr)); // [object Array]
console.log(toString.call(fun)); // [object Function]
console.log(toString.call(date)); // [object Date]
console.log(toString.call(reg)); // [object RegExp]
console.log(toString.call(err)); // [object Error]
console.log(toString.call(arg)); // [object Arguments]
console.log(toString.call(symbol1)); // [object Symbol]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
终极检测方法
/**
* @desc 数据类型检测
* @param obj 待检测的数据
* @return {String} 类型字符串
*/
function type(obj) {
return typeof obj !== "object" ? typeof obj : Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
2
3
4
5
6
7
8
数据类型的单独检测
/**
* @desc 是否是 Undefined 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isUndefined(obj) {
return obj === void 0;
}
/**
* @desc 是否是 Null 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isNull(obj) {
return obj === null;
}
/**
* @desc 是否是 Boolean 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isBoolean(obj) {
return typeof(obj) === 'boolean';
}
/**
* @desc 是否是 Number 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isNumber(obj) {
return typeof(obj) === 'number';
}
/**
* @desc 是否是 String 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isString(obj) {
return typeof(obj) === 'string';
}
/**
* @desc 是否是 Object 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/**
* @desc 是否是 Array 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isArray(obj){
return Array.isArray?Array.isArray(obj):Object.prototype.toString.call(obj) === '[object Array]';
}
/**
* @desc 是否是 Function 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isFunction(obj){
return typeof(obj) === 'function';
}
/**
* @desc 是否是 Date 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isDate(obj){
return Object.prototype.toString.call(obj) === '[object Date]';
}
/**
* @desc 是否是 RegExp 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isRegExp(obj){
return Object.prototype.toString.call(obj) === '[object RegExp]';
}
/**
* @desc 是否是 Error 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isError(obj){
return Object.prototype.toString.call(obj) === '[object Error]';
}
/**
* @desc 是否是 Arguments 类型检测
* @param obj 待检测的数据
* @return {Boolean} 布尔值
*/
function isArguments(obj){
return Object.prototype.toString.call(obj) === '[object Arguments]';
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
instanceof
为了更方便地鉴别引用类型,可以使用 JavaScript的instanceof 操作符。
nul instanceof Object; // false
obj instanceof Object; // true
arr instanceof Array; // true
fun instanceof Function; // true
date instanceof Date; // true
reg instanceof RegExp; // true
err instanceof Error;// true
arr instanceof Object; // true
2
3
4
5
6
7
8
每种引用类型的对象都被正确鉴别为 Object 的实例
其他
undefined == null // true
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');
console.log(typeof symbol1);
// expected output: "symbol"
console.log(symbol3.toString());
// expected output: "Symbol(foo)"
console.log(Symbol('foo') === Symbol('foo'));
// expected output: false
2
3
4
5
6
7
8
9
10
11
12
鉴别数组
虽然 instanceof 可以鉴别数组,但是有一个例外会影响网页开发者:JavaScript 的值可以在同一个网页的不同框架之间传来传去。 当你试图鉴别一个引用值的类型时,这就有可能成为一个问题,因为每一个页面拥有它自己的全局上下文——Object、Array 以及其他内建类型的版本。结果,当你把一个数组从一个框架传到另一个框架时,instanceof就无法识别它,因为那个数组是来自不同框架的 Array 的实例。 为了解决这个问题,ECMAScript 5 引入了 Array.isArray()来明确鉴别一个值是否为 Array 的实例,无论该值来自哪里,该方法对来自任何上下文的数组都返回true。如果你的环境兼容 ECMAScript5,Array.isArray()是鉴别数组的最佳方法。
属性探测:判断属性是否存在
- 使用in操作符 in会检查自有属性和原型属性
console.log('name' in person) // true or false
- hasOwnProperty() 仅检查自有属性
var person1 = {
name:'xinxin'
}
console.log('name' in person1); // true
console.log('toString' in person1); // true
console.log(person1.hasOwnProperty('name')); // true
console.log(person1.hasOwnProperty('toString')); // false
2
3
4
5
6
7
8
9
属性枚举:
可枚举属性
- for-in
- Object.keys() 获取可枚举属性数组
属性特征:
通用特征
- enumerable 是否可以遍历该属性
- configurable 该属性是否可配置
想改变属性特征的话,可以使用Objec.defineProperty()方法
var person = {
name:'xinxin'
};
Object.defineProperty(person,'name',{
enumerable:false
});
console.log(person.propertyIsEnumerable('name'));// false
Object.defineProperty(person,'name',{
configurable:false
});
delete person.name;
console.log('name' in person); // true
console.log(person.name);// 'xinxin'
Object.defineProperty(person,'name',{ // Error
configurable:false
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
从上述例子可看出无法将一个不可配置的属性改为可配置
数据属性特征
- value
- writable
属性访问器特征
- get
- set
最上层的原型对象Object.prototype有如下属性: [[Prototype]] : null hasOwnProperty:(function) propertyIsEnumerable:(function) isPrototypeOf:(function) toString:(function) valueOf:(function)