为什么4不是Number的实例?

时间:2009-01-23 10:06:10

标签: javascript

好奇:

  • 4 instanceof Number =>假
  • new Number(4)instanceof Number =>真?

这是为什么?与字符串相同:

  • 'some string' instanceof String返回false
  • new String('some string') instanceof String =>真
  • String('some string') instanceof String也会返回false
  • ('some string').toString instanceof String也会返回false

对于对象,数组或函数类型,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
/[a-z]/.is();                 //=> RegExp
'5'.is(Number);               //=> false
'5'.is(String);               //=> true

5 个答案:

答案 0 :(得分:62)

value instanceof ConstructorConstructor.prototype.isPrototypeOf(value)相同,并检查{[1]}的[[原型]] - 链是否出现特定对象。

字符串和数字是原始值,而不是对象,因此没有[[Prototype]],因此它只有在将它们包装在常规对象(称为“拳击”)时才有效在Java)。

另外,正如您所注意到的,valueString(value)执行不同的操作:如果在不使用new String(value)运算符的情况下调用内置类型的构造函数,则会尝试转换('cast')特定类型的参数。如果使用new运算符,则会创建包装器对象。

new大致相当于new String(value),其行为与Object(String(value))相同。


JavaScript中的更多类型:ECMA-262定义了以下基本类型:未定义 Null 布尔数字 String 。此外,对于具有属性的事物,还有 Object 类型。

例如,函数的类型为 Object (它们只有一个名为[[Call]]的特殊属性),new Object(String(value)) Null <的原始值/ em>的。这意味着null运算符的结果并不真正返回值的类型...

另外,JavaScript对象还有另一个名为[[Class]]的属性。您可以通过typeof获取此信息(这将返回Object.prototype.toString.call(value) '[object Classname)。数组和函数的类型为 Object ,但它们的类是 Array Function

上面给出的对象类的测试在]'失败时起作用(例如,当对象在窗口/框架边界之间传递并且不共享相同的原型时)。


此外,您可能希望查看此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; } } ),对于的包装对象,它将返回5 class Number (例如'number'),它会返回new Number(5);

  • 对于函数,它将返回'Number'

如果您不想区分原始值和包装器对象(无论是什么,可能是不好的原因),请使用'Function'

已知错误是IE中的一些内置函数,当与某些COM +对象一起使用时,它们被视为typeOf(...).toLowerCase()并且返回值为'Object'

答案 1 :(得分:13)

您可以尝试评估:

>>> typeof("a")
"string"
>>> typeof(new String("a"))
"object"
>>> typeof(4)
"number"
>>> typeof(new Number(4))
"object"

答案 2 :(得分:2)

正如Christoph的回答所述,字符串和数字文字与String和Number对象不同。如果您在文字上使用任何字符串或数字方法,请说

'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()进行类型转换:

//true
alert( Number('5') === 5 )

//false
alert( '5' === 5 )

答案 3 :(得分:1)

这是我发现的一些Javascript的细微差别。如果LHS不是instanceof类型,则object运算符将始终为false。

请注意,new String('Hello World')不会产生string类型,而是objectnew运算符始终生成一个对象。我看到了这样的事情:

function fnX(value)
{
     if (typeof value == 'string')
     {
          //Do stuff
     }
}
fnX(new String('Hello World'));

期望是“Do Stuff”会发生,但它不会发生,因为值的类型是对象。

答案 4 :(得分:1)

对于原始数字,isNaN方法也可以帮助您。