为什么4不是Number的一个实例?
只是好奇:
- 4 instanceof Number => false
- 新号码(4)instanceof Number => true?
为什么是这样? 与string一样:
-
'some string' instanceof String
返回false -
new String('some string') instanceof String
=> true -
String('some string') instanceof String
也返回false -
('some string').toString instanceof String
也返回false
对于对象,数组或函数types,instanceof运算符按预期工作。 我只是不知道如何理解这一点。
[ 新见解 ]
Object.prototype.is = function() { var test = arguments.length ? [].slice.call(arguments) : null ,self = this.constructor; return test ? !!(test.filter(function(a){return a === self}).length) : (this.constructor.name || (String(self).match ( /^function\s*([^\s(]+)/im ) || [0,'ANONYMOUS_CONSTRUCTOR']) [1] ); } // usage var Newclass = function(){}; // anonymous Constructor function var Some = function Some(){}; // named Constructor function (5).is(); //=> Number 'hello world'.is(); //=> String (new Newclass()).is(); //=> ANONYMOUS_CONSTRUCTOR (new Some()).is(); //=> Some /[az]/.is(); //=> RegExp '5'.is(Number); //=> false '5'.is(String); //=> true
value instanceof Constructor
与Constructor.prototype.isPrototypeOf(value)
相同,都检查特定对象的[[Prototype]] – value
链。
string和数字是原始值 ,而不是对象,因此没有[[Prototype]],因此只有在将它们包装在常规对象(在Java中称为“装箱”)时才会起作用。
另外,正如你注意到的那样, String(value)
和new String(value)
做了不同的事情:如果你不使用new
运算符来调用内buildtypes的构造函数,他们会尝试将参数转换('cast')为具体types。 如果你使用new
运算符,他们创build一个包装对象。
new String(value)
大致等价于Object(String(value))
,其行为方式与new Object(String(value))
。
还有一些关于JavaScript的types:ECMA-262定义了以下基本types: 未定义 , 空值 , 布尔值 , 数字和string 。 另外,还有Objecttypes的东西有属性。
例如,函数的types为Object (它们只有一个叫做[[Call]]的特殊属性,而null
是types为Null的原始值。 这意味着typeof
运算符的结果并不真正返回值的types…
另外,JavaScript对象具有另一个名为[[Class]]的属性。 你可以通过Object.prototype.toString.call(value)
得到它(这将返回'[object
Classname
]'
)。 数组和函数的types是Object ,但是它们的类是Array和Function 。
上面给出的对象类的testing在instanceof
失败时(例如当对象在窗口/框架边界之间传递并且不共享相同的原型时)工作。
另外,你可能想看看这个改进版本的typeof
:
function typeOf(value) { var type = typeof value; switch(type) { case 'object': return value === null ? 'null' : Object.prototype.toString.call(value). match(/^\[object (.*)\]$/)[1] case 'function': return 'Function'; default: return type; } }
对于原语,它将以小写字母返回它们的types ,对于对象,它将在标题大小写中返回它们的类 。
例子:
-
对于Number types的基本types (例如
5
),它将返回'number'
,对Numbertypes的包装对象(例如new Number(5)
)返回'Number'
。 -
对于函数,它将返回
'Function'
。
如果你不想区分原始值和包装对象(对于任何可能的原因),使用typeOf(...).toLowerCase()
。
已知的错误是IE中的一些内置函数,当与一些COM +对象一起使用时,它们被认为是'Object'
和返回值'unknown'
。
您可以尝试评估:
>>> typeof("a") "string" >>> typeof(new String("a")) "object" >>> typeof(4) "number" >>> typeof(new Number(4)) "object"
如Christoph的回答所述,string和数字字面与string和数字对象不同。 如果你使用字面上的任何string或数字方法,说
'a string literal'.length
文字被临时转换为一个对象,该方法被调用,对象被丢弃。
文字与对象相比具有明显的优势。
//false, two different objects with the same value alert( new String('string') == new String('string') ); //true, identical literals alert( 'string' == 'string' );
总是使用文字来避免意外的行为!
如果需要,可以使用Number()和String()来进行types转换:
//true alert( Number('5') === 5 ) //false alert( '5' === 5 )
这是一个Javascript的细微差别,我发现一些出。 如果LHS不是object
types,则运算符的instanceof
将始终为false。
请注意, new String('Hello World')
不会产生string
types,而是一个object
。 new
运算符总是导致一个对象。 我看到这样的事情:
function fnX(value) { if (typeof value == 'string') { \\Do stuff } } fnX(new String('Hello World'));
期望是“ Do Stuff
”会发生,但不是因为价值的types是对象。
在原始数字的情况下, isNaN
方法也可以帮助你。