为什么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 ConstructorConstructor.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 ,但是它们的类是ArrayFunction

上面给出的对象类的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不是objecttypes,则运算符的instanceof将始终为false。

请注意, new String('Hello World')不会产生stringtypes,而是一个objectnew运算符总是导致一个对象。 我看到这样的事情:

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

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

在原始数字的情况下, isNaN方法也可以帮助你。