Javascript 为什么4不是数字的一个实例?

Javascript 为什么4不是数字的一个实例?,javascript,Javascript,只是好奇: 4 instanceof Number=>false 新数字(4)实例数=>真 为什么会这样?与字符串相同: 字符串的'some string'实例返回false 新字符串(“某些字符串”)字符串实例 String('some String')instanceof String也返回false ('some string')。toString instanceof string也返回false 对于对象、数组或函数类型,instanceof运算符按预期工作。我只是不知道如何理

只是好奇:

  • 4 instanceof Number=>false
  • 新数字(4)实例数=>真
为什么会这样?与字符串相同:

  • 字符串的'some string'实例
    返回false
  • 新字符串(“某些字符串”)字符串实例
  • 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

构造函数的
value instanceof
Constructor.prototype.isPrototypeOf(value)
相同,并检查
value
的[[prototype]]-链是否出现特定对象

字符串和数字是基本值,而不是对象,因此没有[[Prototype]],因此只有将它们包装在常规对象中(在Java中称为“装箱”)才能工作

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

新字符串(值)
大致相当于
对象(字符串(值))
,其行为方式与
新对象(字符串(值))
相同


关于JavaScript中类型的更多信息:ECMA-262定义了以下基本类型:未定义、Null、Boolean、Number和String。此外,还有一个类型对象,用于具有属性的对象

例如,函数属于Object类型(它们只有一个名为[[Call]]的特殊属性),而
null
是null类型的基本值。这意味着
typeof
运算符的结果实际上不会返回值的类型

另外,JavaScript对象还有另一个名为[[Class]]的属性。您可以通过
Object.prototype.toString.call(value)
获得它(这将返回
'[Object
]
)。数组和函数属于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
    ),它将返回
    'Number'
    ,对于数字的包装对象(例如
    新数字(5)
    ),它将返回
    'Number'

  • 对于函数,它将返回
    “函数”

如果您不想区分原语值和包装器对象(无论出于什么原因,可能是不好的原因),请使用
typeOf(…).toLowerCase()


已知bug是IE中的一些内置函数,当与某些COM+对象一起使用时,它们被认为是
'Object'
,返回值为
'unknown'

您可以尝试评估:

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

这是Javascript的一个细微差别,我发现它抓住了一些要点。如果LHS不是
对象
类型,则运算符的
实例将始终导致false

请注意,
newstring('helloworld')
不会产生
String
类型,而是一个
对象。
new
操作符总是生成一个对象。我看到这样的事情:

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

预期会发生“
Do Stuff
”,但不会发生,因为值的类型是object。

正如Christoph的回答中所述,字符串和数字文本与字符串和数字对象不同。如果对文本使用任何字符串或数字方法,则

'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 )

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

@annakata:检查ECMA-262。这些类型称为未定义、Null、Boolean、Number、String和Object;无论什么
typeof
返回…@Christoph,这都很重要,因为包装器对象是大写的,typeof是小写的,没有其他东西可以访问。因此,约定和实践是以小写形式引用数据类型,如下所述:@annakata:
typeof
被破坏-其返回值与实际类型无关!好吧,我想你是按照规范去做的,我是按照实践去做的,在这种情况下,我认为这是正确的。我认为引用相同格式的类型和包装器对象是不明智的,但我不会进一步编辑您的帖子。我认为字符串和数字是基本值,而不是对象,因此没有[[Prototype]]
示例:
(新数字(123))。\uuuuu proto\uu==(123)。\uu proto\uu;/true
您必须使用
Number.prototype.isPrototypeOf(inp)
-如果操作正确,您的方法也会起作用:
inp.constructor==Number
;它可能会失败,因为
constructor
只是原型的一个属性,可以被覆盖!我不确定我是否理解你所说的“可以覆盖”是什么意思。这并不意味着我可以用一些ot覆盖构造函数