使用构造函数名称作为类型的可靠性如何

How reliable is using the constructors name as type?

本文关键字:类型 可靠性 构造函数      更新时间:2023-09-26

我最近看到了很多这样的情况,甚至在编译成javascript的新编程语言中,他们用item.constructor.name取代了typeof

这有多可靠?有什么优点(数组类型除外)和缺点吗?

这里有一个例子

var tmp = [];
typeof tmp // object
tmp.constructor.name // Array

name作为函数属性是即将到来的ES6标准的一部分,目前除IE外所有浏览器都支持。除此之外,它应该可以用于内置对象。

由用户定义的构造函数OTOH创建的对象可能没有正确的constructor属性设置,例如,在使用继承但constructor的值没有设置回构造函数的情况下:

Child.prototype = Object.create(Parent.prototype);
// Child.prototype.constructor = Child;

tl;博士:

内置对象和非ie浏览器:可靠
第三方用户定义的构造函数或IE:不可靠

这是我想到的一些缺点:

1)浏览器支持

Felix Kling的回答涵盖了它,non-IE工作得很好。IE -没有那么多,虽然我想变通办法是可能的。

2)自定义构造函数
var Foo = function(){};
var foo = new Foo();
console.log(foo.constructor.name); // empty string

当然,这可以通过强制一种不允许构造函数是匿名函数的风格来缓解,或者发明一个疯狂的解决方案。

var Foo = function Foo(){};
function Bar(){};
var Baz = function (){};
Baz.name = 'Baz';
<<p> 3)异常/strong>

typeof不会抛出异常。因此,它用于检查变量是否尚未定义:

if (typeof baz === 'undefined') console.log('baz not defined');
if (baz === undefined) console.log('Reference error instead!');

更糟糕的是,检查constructor.name会抛出一个TypeError来处理空值和未定义值。这可以通过使用:

来缓解
foo != null && foo.constructor.name

4)封装对象

在某些极端情况下,typeof和item.constructor.name返回冲突的结果:

var foo = false;
var bar = new Boolean(false);
console.log(typeof foo);  // boolean
console.log(typeof bar);  // object
console.log(foo.constructor.name);  // Boolean
console.log(bar.constructor.name);  // Boolean
if (foo) console.log('No');
if (bar) console.log('Yes');

这些实际上很重要的场景很少,上面的几乎是最坏的情况。

5)速度

我希望一个本地操作符比2个属性检查快得多,尽管如果这个想法得到关注,它可能也会得到更好的优化。无论哪种方式,我都无法想象这会成为应用程序的瓶颈。


总而言之,它有不少缺点,我想不出一个强有力的理由来使用它