这是确定JavaScript变量类型的有效方法吗?
任何编写JS的开发人员迟早都会遇到这种相当令人恼火的行为:这是确定JavaScript变量类型的有效方法吗?,javascript,variables,types,Javascript,Variables,Types,任何编写JS的开发人员迟早都会遇到这种相当令人恼火的行为: typeof []; // 'object' 虽然有一些变通方法,例如instanceof和访问变量的.constructor属性,但我还是想到了这一点: Array.prototype.TYPE = 'Array'; String.prototype.TYPE = 'String'; Boolean.prototype.TYPE = 'Boolean'; Object.prototype.TYPE = 'Object'; RegEx
typeof []; // 'object'
虽然有一些变通方法,例如instanceof
和访问变量的.constructor
属性,但我还是想到了这一点:
Array.prototype.TYPE = 'Array';
String.prototype.TYPE = 'String';
Boolean.prototype.TYPE = 'Boolean';
Object.prototype.TYPE = 'Object';
RegExp.prototype.TYPE = 'RegExp';
Number.prototype.TYPE = 'Number';
// and therefore:
[1,2,'bar', {baz: 'foo'}].TYPE === 'Array'; // true
"But life itself, my wife, and all the world / Are not with me esteemed above thy life".TYPE // 'String'
(42).TYPE === 'Number'; // true
// and so on
我知道人们普遍不赞成修改原生原型,也就是说,这种“模式”还有其他问题吗
更新:
一些注释提供了替代解决方案,如使用Object.prototype.toString
等。这些当然都是有用例的有效方法。但是,我主要感兴趣的是,在某些情况下,向本机构造函数原型添加属性是否会导致问题:)
更新:
更安全的方法
Array.prototype.getType = function() {return 'Array'};
String.prototype.getType = function() {return 'String'};
Boolean.prototype.getType = function() {return 'Boolean'};
Object.prototype.getType = function() {return 'Object'};
RegExp.prototype.getType = function() {return 'RegExp'};
Number.prototype.getType = function() {return 'Number'};
道格拉斯·克罗克福德正是出于这个原因:
。。。新的typeOf
全局功能旨在替换有缺陷的typeOf
操作员。它产生与typeof相同的结果,只是它为null
返回'null'
,为数组返回'array'
他这样做:
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (typeof value.length === 'number' &&
!(value.propertyIsEnumerable('length')) &&
typeof value.splice === 'function') {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
typeOf({}) //=> "object"
typeOf([]) //=> "array"
@xcezzz这是一个很好的方法,但是关于
typeof{}==typeof[]//true
?@Anatol你刚刚偶然发现了为什么typeof{}==typeof[]
-“我希望对象
适用于所有对象。”它们是相等的,因为数组
是对象
和函数
一样,等等。只有原语值不是Object
s。其他已识别的“类型”仅因特殊行为而给出,例如,'function'
s是可调用的。@Anatol但它不是一个简单的对象。对象是使用{}
或新对象()创建的。
@Derek朕會功夫 是的,String
s是Object
s,但在装箱之前(通常由属性访问器)不是String
s。isfalse
@Anatol我建议在构造函数本身上使用“静态”方法,如下示例所示。这些属性不会干扰或冲突实例属性。下划线包括你可以使用或作为灵感。我很乐意接受这个建议,并将这个片段添加到我的标准版本中,非常感谢!尽管如此,我还是对为什么不应该像我最初的问题中那样做感兴趣,因为你正在改变你的代码将要与之交互的每一段代码的期望,以及每一个在你之后将要处理你的代码的开发人员的期望。如果有一个很好的理由这么做,我会说继续,但这不是一个很好的理由。你在制造一个真正没有问题的问题。您希望能够区分[]
和{}
之间的区别,但是您正在修改六个内置对象来实现这一点,并创建自己的伪类型系统。回到你的实际问题,[]
vs{}
,选择占地面积最小的更简单的解决方案。@meagar你的推理是完美的,你用我的想法找出了潜在的谬误,谢谢!