JS关于判断类型那些事
程序员文章站
2022-05-05 14:26:08
...
为啥写这篇文章,是因为最近面试的时候面试官问了一个问题:你如何判断传入的数据是一个对象还是一个数组?所以打算把JS中类型判断这块知识点好好的总结一下。
JS中判断类型的方法基本有以下几个:
- typeof
- Object.prototype.toString
- constructor
- instanceof
它们各自的用法如下:
- typeof xxx 但是typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果:number,boolean,string,function(函数),object(NULL,数组,对象),undefined。正因为typeof遇到null,数组,对象时都会返回object类型,所以当我们要判断一个对象是否是数组时不能用typeof这种方法,实际上typeof只有一个实际应用场景,就是用来检测一个对象是否已经定义或者是否已经赋值。而这个应用却不是来检查对象的类型。
- Object.prototype.toString.call(xxx) 该方法返回描述某个对象数据类型的字符串,如自定义的对象没有被覆盖,则会返回“[object type]”,其中,type则是实际的对象类型。在使用该方法检测的时候,可以使用Object.prototype.toString.call()或者Object.prototype.toString.apply()进行测试,如:
var toString = Object.prototype.toString;
toString.call(new Date);//[object Date]
toString.call(new String);//[object String]
toString.call(Math);//[object Math]
toString.call(undefined);//[object Undefined]
toString.call(null);//[object Null]
因此,引出Object.prototype.toString.call(obj).slice(8,-1),如
Object.prototype.toString.call('ESStudio balabala……');
//"[object String]"
Object.prototype.toString.call('ESStudio balabala……').slice(8,-1);
//"String"
slice(startIndex,endIndex),从0开始索引,其中8代表从第8位(包含)开始截取(本例中代表空格后面的位置),-1代表截取到倒数第一位(不含),所以正好截取到[object String]中的String,注意第0位是"["。
- constructor 定义:constructor 属性返回对创建此对象的数组函数的引用。
语法:object.constructor
<script type="text/javascript">
function employee(name,job,born)
{
this.name=name;
this.job=job;
this.born=born;
}
var bill=new employee("Bill Gates","Engineer",1985);
document.write(bill.constructor);
</script>
输出结果:
function employee(name, job, born)
{this.name = name; this.job = job; this.born = born;}
不过我们可以自己定义一个函数通过constructor属性来帮助我们实现判断一个数据的类型
function getConstructiorName(obj) {
return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)/)[1];
}
getConstructiorName([]) === "Array"; // true
- instanceof 定义:instanceof 左操作数是一个类,右操作数是标识对象的类。如果左侧的对象是右侧类的实例,则返回true。而js中对象的类是通过初始化它们的构造函数来定义的。即instanceof的右操作数应当是一个函数。所有的对象都是object的实例。如果左操作数不是对象,则返回false,如果右操作数不是函数,则抛出typeError。
instanceof 运算符是用来测试一个对象是否在其原型链原型构造函数的属性。
语法:object instanceof constructor
instanceof 操作符用来比较两个操作数的构造函数。只有在比较自定义的对象时才有意义。 如果用来比较内置类型,将会和 typeof 操作符 一样用处不大。
比较自定义对象时:
function Foo() {}
function Bar() {}
Bar.prototype = new Foo();
new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true
// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例
Bar.prototype = Foo;
new Bar() instanceof Foo; // false
比较内置类型时:
new String('foo') instanceof String; // true
new String('foo') instanceof Object; // true
'foo' instanceof String; // false
'foo' instanceof Object; // false
注意:instanceof 用来比较属于不同 JavaScript 上下文的对象(比如,浏览器中不同的文档结构)时将会出错, 因为它们的构造函数不会是同一个对象。
结论:instanceof 操作符应该仅仅用来比较来自同一个 JavaScript 上下文的自定义对象。 正如 typeof 操作符一样,任何其它的用法都应该是避免的。
以上,就是个人参照其他文章和笔记做出来的一个总结,如果喜欢的话,麻烦一键三连支持一下,感谢!
文章参考链接:https://www.jb51.net/article/149429.htm
https://www.w3school.com.cn/jsref/jsref_constructor_array.asp
http://caibaojian.com/fend_note/chapter2/11_js_type_determin.html