JavaScript系列之类型识别

一.可以使用typeof操作符来检测变量的数据类型

var abc;
alert(typeof abc); // undefined

var abc = true;
alert(typeof abc); // boolean

var abc = 123;
alert(typeof abc); // number

var s = 'abc';
alert(typeof s); // string

var abc = function(){};
alert(typeof abc); // function

var abc = {}; //[] , null
alert(typeof abc); // object

var s = Symbol();
alert(typeof s); // symbol
  • typeof的局限性
typeof在判断对象类型时有局限性。
let d = new Date();
let a = [];
let n = null;
let r = /\d+/;
consolel.log(typeof d); // object
consolel.log(typeof a); // object
consolel.log(typeof n); // object
consolel.log(typeof r); // object

二.obj instanceof constructor

  • 判断变量是否是给定类的实例。
let d = new Date();
let a = [];
let n = null;
let r = /\d+/;
consolel.log(d instanceof Date); // true
consolel.log(a instanceof Array); // true
consolel.log(n instanceof Object); // false
consolel.log(r instanceof RegExp); // true
  • instanceof也可以识别自定义类型的实例
function Foo() {}
function Bar() {}
Bar.prototype = new Foo();
alert(new Bar() instanceof Bar); // true
alert(new Bar() instanceof Foo); // true
  • 由于Array也是从Object继承过来的
let a = [];
alert(a instanceof Array); // true
alert(a instanceof Object); // true
  • instanceof无法识别原始类型
alert('123' instanceof String); // false
alert(123 instanceof Number); // false
这里有一点需要注意:instanceof不是得到某个变量的类型,而是在判断变量是否是某个类型

三.constructor

  • 可以检测变量的构造函数
alert(({x: 1}).constructor.name); // Object
alert(([]).constructor.name); // Array
alert((new Date).constructor.name); // Date
alert(('').constructor.name); // String
alert((true).constructor.name); // Boolean
alert((12).constructor.name); // Number
alert((null).constructor.name); // TypeError
alert((undefined).constructor.name); // TypeError
  • 也可以检测自定义类型
function Foo() {}
alert((new Foo()).constructor.name); // Foo
  • constructor在某些场景下失效
  • 有原型时失效
function Foo() {}
Foo.prototype = {
	method1: function(){}
}
alert((new Foo()).constructor.name); // Object
  • 多重继承时失效
function a() {}
function b() {}
b.prototype = new a(); // b 继承 a
let f = new b();
alert(f.constructor === b); // false
alert(f.constructor === a); // true
  • instanceof和constructor不可跨frame
  • 需要在同个frame中才有效
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length - 1].Array;
var arr = new xArray(1,2,3); // [1,2,3]
alert(arr instanceof Array); // false
alert(arr.constructor === Array); // false

四.duck-typing

  • 只检测特定的属性,如果存在,则认为是该类型
function isArray(object){
	return object != null && typeof object === 'object' && 
	'splice' in object && 'join' in object;
}

function isArray(arr){
	return !!arr && arr.constructor == Array;
}

五.object.prototype.toString.call(obj)

  • 可以检测对象的内部属性 [ [ class ] ]
function getType(o) {
   return Object.prototype.toString.call(o);
}
let d = new Date();
let a = [];
let r = /\d+/;
console.log(getType(d)); // [object Date]
console.log(getType(a)); // [object Array]
console.log(getType(r)); // [object RegExp]
function getType(o) {
   return Object.prototype.toString.call(o).slice(8,-1);
}
  • 这个方法不能识别自定义类型的
function Foo() {}
alert(getType(new Foo()); // Object

六.类型识别总结

在这里插入图片描述

七.检测数组的原生方法:Array.isArray()

从ES5开始引入的,所以在旧版本的浏览器中是不可以使用的。
// 下面的函数调用都返回true
Array.isArray([]);
Array.isArray([1]);
Array.isArray(new Array());
// 鲜为人知的事实:其实Array.prototype也是一个数组
Array.isArray(Array.prototype);
// 下面的函数调用都返回false
Array.isArray();
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);
Array.isArray(17);
Array.isArray('Array');
Array.isArray(true);
Array.isArray(false);
Array.isArray({__proto__:Array.prototype});
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值