Javascript ECMA-5是否存在新类型的运算符(或函数)?

Javascript ECMA-5是否存在新类型的运算符(或函数)?,javascript,ecmascript-5,Javascript,Ecmascript 5,我认为JavaScript有5种基本类型(null、undefined、boolean、number、string),然后是object(包括数组、函数和自定义的伪类对象)。但有点奇怪的是 typeof null 是“object”,并且对于伪经典类,例如Person,Author,没有简单的方法可以获取对象类名。我想知道是否有更新的运算符或函数可以为基元类型返回可能的小写名称(对于null“null”,而不是“object”),对于自定义的伪经典对象返回大写 如果ECMA-5或更高版本中不存

我认为JavaScript有5种基本类型(null、undefined、boolean、number、string),然后是object(包括数组、函数和自定义的伪类对象)。但有点奇怪的是

typeof null
“object”
,并且对于伪经典类,例如
Person
Author
,没有简单的方法可以获取对象类名。我想知道是否有更新的运算符或函数可以为基元类型返回可能的小写名称(对于
null
“null”,而不是
“object”
),对于自定义的伪经典对象返回大写


如果ECMA-5或更高版本中不存在这样的运算符或函数,使用它是否有意义?否则,我们可能需要依赖于我们自己的定义或任何框架,但这不是不同平台的标准。

您现在可以在所有浏览器中执行此操作

任何对象的
构造函数
属性都将返回拥有该对象原型的函数

function Person() { }
alert(new Person().constructor === Person) //true

您现在可以在所有浏览器中执行此操作

任何对象的
构造函数
属性都将返回拥有该对象原型的函数

function Person() { }
alert(new Person().constructor === Person) //true

typeof
的行为由规范表20规定:

表20-操作员结果类型

val结果的类型
-----------------------------------------------------------------------------------
未定义“未定义”
-----------------------------------------------------------------------------------
空“对象”
-----------------------------------------------------------------------------------
布尔“布尔”
-----------------------------------------------------------------------------------
数字“数字”
-----------------------------------------------------------------------------------
字符串“字符串”
-----------------------------------------------------------------------------------
对象(本机而非本机)
实现[[Call]])“对象”
-----------------------------------------------------------------------------------
对象(本机或主机)
并且实现了[[Call]])“函数”
-----------------------------------------------------------------------------------
对象(主机),未定义实现,但可能未定义
实现[[Call]])“未定义”、“布尔”、“数字”或“字符串”。
(大写的
Null
是一种内部类型,其唯一值为
Null

这似乎只是一个惯例
null instanceof Object
false
,因此,正如预期的那样,
null
显然不是一个对象

您请求的操作员不存在。要计算名称,可以使用
==null
测试
null
,并使用
typeof
测试其他原语。至于“自定义伪经典对象”,您可以使用的工具有:

  • 功能。
    原型
  • 对象。

(从中列出,您可以看到一些示例。)

规范规定了
typeof
的行为,表20:

表20-操作员结果类型

val结果的类型
-----------------------------------------------------------------------------------
未定义“未定义”
-----------------------------------------------------------------------------------
空“对象”
-----------------------------------------------------------------------------------
布尔“布尔”
-----------------------------------------------------------------------------------
数字“数字”
-----------------------------------------------------------------------------------
字符串“字符串”
-----------------------------------------------------------------------------------
对象(本机而非本机)
实现[[Call]])“对象”
-----------------------------------------------------------------------------------
对象(本机或主机)
并且实现了[[Call]])“函数”
-----------------------------------------------------------------------------------
对象(主机),未定义实现,但可能未定义
实现[[Call]])“未定义”、“布尔”、“数字”或“字符串”。
(大写的
Null
是一种内部类型,其唯一值为
Null

这似乎只是一个惯例
null instanceof Object
false
,因此,正如预期的那样,
null
显然不是一个对象

您请求的操作员不存在。要计算名称,可以使用
==null
测试
null
,并使用
typeof
测试其他原语。至于“自定义伪经典对象”,您可以使用的工具有:

  • 功能。
    原型
  • 对象。

(从中可以看到一些示例的列表。)

ECMAScript 5对象的内部属性称为
[[Class]]]
。这是ES5中最接近您要求的内容。您可以使用
Object.prototype.toString
访问
[[Class]]]
,如下所示:

function getClassOf(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
}

getClassOf([ ]); // => "Array"
getClassOf(new Date()); // => "Date"
getClassOf(function() { }); // => "Function"
getClassOf(3); // => "Number"
getClassOf(true) // => "Boolean"
getClassOf(document.createElement('div')); // => "HTMLDivElement"
getClassOf(Math); // => "Math"
getClassOf(null); // => "Null"
getClassOf(undefined); // => "Undefined"
getClassOf({ x: 1 }); // => "Object"
此行为对于充分识别来自其他帧的对象至关重要

但是,它不适用于用户定义的构造函数。使用用户定义的构造函数创建的对象具有
[[Class]]
“对象”

看起来ECMAScript 6可能具有
function getTypeOf(value) {

    // Return "null" for null.
    if (value === null) return 'null';

    // Return primitive types.
    var type = typeof value;
    if (type != 'object') return type;

    // Return [[Class]] if available for objects.
    type = Object.prototype.toString.call(value).slice(8, -1);
    if (type != 'Object') return type;

    // Return "Object" if it wasn't created with another constructor.
    var proto = Object.getPrototypeOf(value);
    if (proto == Object.prototype)
        return 'Object';

    // Return the constructor name if constructor hasn't been
    // modified on the object.
    if (value.constructor && proto === value.constructor.prototype)
        return value.constructor.name;

    // Return the constructor name if constructor hasn't been
    // modified on the prototype.
    if (proto.constructor && proto === proto.constructor.prototype)
        return proto.constructor.name;

    // Return "???" if the type is indeterminable.
    return '???';

}
getTypeOf([ ]); // => "Array"
getTypeOf(new Date()); // => "Date"
getTypeOf(function() { }); // => "Function"
getTypeOf(3); // => "number"
getTypeOf(true) // => "boolean"
getTypeOf(document.createElement('div')); // => "HTMLDivElement"
getTypeOf(Math); // => "Math"
getTypeOf(null); // => "null"
getTypeOf(undefined); // => "undefined"
getTypeOf({ x: 1 }); // => "Object"

function Foo() { }
var foo = new Foo();

getTypeOf(foo); // => "Foo"

// If the constructor property is changed, still works.
foo.constructor = function FakeConstructor() { };
getTypeOf(foo); // => "Foo"

// If the constructor property AND the prototype's constructor is
// changed, result is "???".
foo.constructor = function FakeConstructor() { };
Foo.prototype.constructor = function FakeConstructor2() { };
getTypeOf(foo); // => "???"