为什么4不是 Number 的实例?

只是好奇:

  • 4 instanceof Number = > false
  • 新号码(4) instanceof Number = > true?

- 为什么会这样?-字符串也是一样:

  • 'some string' instanceof String返回 false
  • new String('some string') instanceof String = > true
  • 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
44833 次浏览

value instanceof ConstructorConstructor.prototype.isPrototypeOf(value)相同,两者都检查 value的[[ Prototype ]]-链以查找特定对象的出现。

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

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

new String(value)大致相当于 Object(String(value)),它的行为方式与 new Object(String(value))相同。


关于 JavaScript 中的类型的更多信息: ECMA-262定义了以下基本类型: 不确定无效布尔型号码绳子。此外,对于具有属性的事物,还有 反对类型。

例如,函数的类型是 反对(它们只有一个名为[[ Call ]]的特殊属性) ,而 null无效类型的基元值。这意味着 typeof运算符的结果并不真正返回值的类型..。

此外,JavaScript 对象还有另一个名为[[ Class ]]的属性。你可以通过 Object.prototype.toString.call(value)得到它(这将返回 '[objectClassname]')。数组和函数的类型是 反对,但它们的类是 数组功能

上面给出的对象类的测试在 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'; 对于 同学们 号码的包装对象(例如 new Number(5)) ,它将返回 'Number';

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

如果您不想区分基元值和包装器对象(无论出于什么原因,可能是不好的原因) ,那么使用 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 不是 object类型,操作符的 instanceof将总是导致 false。

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

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

期望“ Do Stuff”会发生,但是没有发生,因为值的类型是 object。

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

对于基元数字,isNaN方法也可以帮助您。