您的位置:首页 > 移动开发 > Objective-C

实例详解JS中的类型检测2:constructor和Object.prototype.string.call

2018-03-09 13:45 686 查看
三、constructor

我们在浏览器中输入如下代码进行测试:

null.constructor===Null;//报错
undefined.constructor===Undefined;//报错

1.constructor===Number;//报错
NaN.constructor===Number;//true
Infinity.constructor===Number;//true
"hello".constructor===String;//true
false.constructor===Boolean;//true

var a={};
a.constructor===Object;//true
[].constructor===Array;//true
/\.jpg$/.constructor===RegExp;//true
var b=function(){};
b.constructor===Function;//true
var c=new Date();
c.constructor===Date;//true

b.constructor===Object;//false
c.constructor===Object;//false


我们看到,constructor和instanceof检测有一定相似性,又有一些不同,总结如下:

1、constructor无法检测基本类型,但却可以检测NaN和Infinity是Number类型。

2、constructor可以检测引用类型;

3、constructor和instanceof不同的重要一点是:constructor不会检测实例的原型链上是否有对应构造函数,而是检测到最近的构造函数就结束。

四、Object.prototype.toString.call

首先,prototype表明toString是Object构造函数的原型对象的一个方法,作用是转换为字符串数据类型,我们可能产生这样一个猜测:直接使用Object.toString也是可以的,我们测试下:

Object.toString({});//"function Object() { [native code] }"
Object.toString(new Function());//"function Object() { [native code] }"
Object.toString(new Date());//"function Object() { [native code] }"
Object.toString(/\.jpg$/);//"function Object() { [native code] }"
Object.toString([]);//"function Object() { [native code] }"
Object.toString(null);//"function Object() { [native code] }"
Object.toString(undefined);//"function Object() { [native code] }"
Object.toString('');//"function Object() { [native code] }"
Object.toString(NaN);//"function Object() { [native code] }"
Object.toString(false);//"function Object() { [native code] }"


不难得出:

结论1:使用Object.toString()的方式无法检测基本类型和引用类型,结果均是”function Object() { [native code] }”。

我们产生另一个想法,是否可以用Object.prototype.toString来测试,不用加call呢?输入以下代码测试:

Object.prototype.toString({});//"[object Object]"
Object.prototype.toString(new Function());//"[object Object]"
Object.prototype.toString(new Date());//"[object Object]"
Object.prototype.toString(/\.jpg$/);//"[object Object]"
Object.prototype.toString([]);//"[object Object]"
Object.prototype.toString(null);//"[object Object]"
Object.prototype.toString(undefined);//"[object Object]"
Object.prototype.toString('');//"[object Object]"
Object.prototype.toString(NaN);//"[object Object]"
Object.prototype.toString(false);//"[object Object]"


这样得出第二个结论:

结论2:使用Object.prototype.toString()的方式无法检测基本类型和引用类型,结果均是”[object Object]”。

由前面两种情况,我们猜测可能call在起着关键作用,我们输入如下代码:

console.log(Object.prototype.toString.call({}));//"[object Object]"
console.log(Object.prototype.toString.call(new Function()));//"[object Function]"
console.log(Object.prototype.toString.call(new Date()));//"[object Date]"
console.log(Object.prototype.toString.call(/\.jpg$/));//"[object RegExp]"
console.log(Object.prototype.toString.call([]));//"[object Array]"
console.log(Object.prototype.toString.call(null));//"[object Null]"
console.log(Object.prototype.toString.call(undefined));//"[object Undefined]"
console.log(Object.prototype.toString.call(''));//"[object String]"
console.log(Object.prototype.toString.call(NaN));//"[object Number]"
console.log(Object.prototype.toString.call(false));//"[object Boolean]"


可以看到基本类型和引用类型都可以检测,因此我们产生第3个结论:

结论3:使用Object.prototype.toString.call()可以检测基本类型和引用类型。

那么,我们是否可以把第一种情况加上call达到目的呢?

console.log(Object.toString.call({}));
console.log(Object.toString.call(new Function()));
console.log(Object.toString.call(new Date()));
console.log(Object.toString.call(/\.jpg$/));
console.log(Object.toString.call([]));
console.log(Object.toString.call(null));
console.l
b135
og(Object.toString.call(undefined));
console.log(Object.toString.call(''));
console.log(Object.toString.call(NaN));
console.log(Object.toString.call(false));


测试发现,仅有当为函数时,才不会报错,显然是无法用来检测的。

**结论4:**Object.toString.call()的方式无法检测基本类型和引用类型,除了函数均会报错。

我们可能产生新的猜测?是否可以将测试的变量放在Object位置呢?如下:

console.log({}.toString());//"[object Object]"
console.log(new Function().toString());//"function anonymous() {}"
console.log(new Date().toString());/*"Fri Mar 09 2018 13:35:34 GMT+0800 (中国标准时间)",视测试时间不同而不同*/
console.log(/\.jpg$/.toString());// /\.jpg$/
console.log([].toString());//''
console.log(null.toString());//报错
console.log(undefined.toString());//报错
console.log(''.toString());//''
console.log(NaN.toString());//NaN
console.log(false.toString());//false


不光如此,我们测试加上prototype一样各种问题,我们产生结论:

结论5:变量名.toString( )和变量名.prototype.toString( )的方式无法检测基本类型和引用类型。

综上,Object.prototype.toString.call是比较完善的方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: