JS类型判定和对象遍历属性方法
JS类型判定
js有六种基本类型:number, string, bool, null, undefined,symbol。还有复杂类型:Array、Function、Object等。
在js中常见类型检查手段的区别:typeof, instanceof, toString。
如果你要判断的是基本数据类型或JavaScript内置对象,使用toString; 如果要判断的时自定义类型,请使用instanceof。
typeof
typeof 操作符返回的是类型字符串,它的返回值有6种取值:1
2
3
4
5
6
7typeof 3 // "number"
typeof "abc" // "string"
typeof {} // "object"
typeof true // "boolean"
typeof undefined // "undefined"
typeof function(){} // "function"
typeof function(){} // "function"instanceof
instanceof操作符用于检查某个对象的原型链是否包含某个构造函数的prototype属性。
instanceof是通过原型链来检查类型的,所以适用于任何”object”的类型检查。1
2
3
4
5
6
7// 比如直接原型关系
function Animal(){ }
(new Animal) instanceof Animal // true
// 原型链上的间接原型
function Cat(){}
Cat.prototype = new Animal
(new Cat) instanceof Animal // true
instanceof也可以用来检测内置兑现,比如Array, RegExp, Object, Function:1
2
3
4[1, 2, 3] instanceof Array // true
/abc/ instanceof RegExp // true
({}) instanceof Object // true
(function(){}) instanceof Function // true
但你可以这样:1
2
3new Number(3) instanceof Number // true
new Boolean(true) instanceof Boolean // true
new String('abc') instanceof String // true
但这时你已经知道数据类型了,类型检查已经没有意义了。
- toString
toString方法是最为可靠的类型检测手段,它会将当前对象转换为字符串并输出。 toString属性定义在Object.prototype上,因而所有对象都拥有toString方法。 但Array, Date等对象会重写从Object.prototype继承来的toString, 所以最好用Object.prototype.toString来检测类型。1
2
3
4
5
6
7
8
9
10
11
12toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(3); // [object Number]
toString.call([]); // [object Array]
toString.call({}); // [object Object]
toString.call(function q(){}); // [object Function]
toString.call(new RegExp('a')); // [object RegExp]
// Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
toString也不是完美的,它无法检测用户自定义类型。 因为Object.prototype是不知道用户会创造什么类型的, 它只能检测ECMA标准中的那些内置类型。
- 总结
typeof只能检测基本数据类型,对于null还有Bug;
instanceof适用于检测对象,它是基于原型链运作的;
toString适用于ECMA内置JavaScript类型(包括基本数据类型和内置对象)的类型判断;
对象遍历属性
顺便说一说关于对象遍历属性的几种方法。
- 遍历可枚举的、自身的属性
使用 Object.keys() 或是 for..in + hasOwnProperty()。
Object.keys()是获取当前对象的所有可枚举、自身的属性;
for..in是获取当前对象包括原型链上的所有可枚举属性;
hasOwnProperty是判断某个属性是否在当前对象上。1
2
3
4// 再用for..of对返回的数组进行遍历
for (let prop of Object.keys(p1)){
console.log(prop);
}
1 | // 得到可枚举、自身+继承的属性 |
遍历所有(可枚举的&不可枚举的)、自身的属性
Object.getOwnPropertyNames方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。要获取属性为Symbols类型的只能通过Object.getOwnPropertySymbols1
2
3
4// 使用 `Object.getOwnPropertyNames()`
for (let prop of Object.getOwnPropertyNames(p1)) {
console.log(prop);
}遍历可枚举的、自身+继承的属性
1
2
3
4// 使用 `for..in`
for (let prop in p1) {
console.log(prop);
}遍历所有的、自身+继承的属性
1
2
3
4
5
6
7
8
9
10var getAllPropertyNames = (obj) => {
var props = [];
do {
props = props.concat(Object.getOwnPropertyNames(obj));
} while (obj = Object.getPrototypeOf(obj));
return props;
};
for (let prop of getAllPropertyNames(p1)) {
console.log(prop);
}