当前位置: 首页 > 面试题库 >

JavaScript获取对象类型的名称

蔚楷
2023-03-14
问题内容

是否有一个JavaScript的等效的Java的class.getName()


问题答案:

是否有与Java等效的JavaScript class.getName()

没有

名称class Foo {}Foo.namething不论类别如何,的类别名称thing均为thing.constructor.name。ES2015环境中的内置构造函数具有正确的name属性;例如(2).constructor.name"Number"

但是,这里有各种各样的骇客,它们都以一种或另一种方式下降:

这是一种可以满足您需要的技巧-请注意,它会修改Object的原型,而人们对此并不满意(通常是出于充分的理由)

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

现在,所有对象都将具有函数,该函数getName()将以字符串形式返回构造函数的名称。我已经在FF3和中对此进行了测试IE7,不能说其他实现。

如果您不想这样做,这里是讨论在JavaScript中确定类型的各种方法…

我最近将其更新为更详尽,尽管并非如此。欢迎更正…

使用constructor属性…

每个属性object都有其值constructor,但是取决于该值的object构造方式以及您要使用该值做什么,它可能有用也可能没有用。

一般来说,您可以使用constructor属性来测试对象的类型,如下所示:

var myArray = [1,2,3];
(myArray.constructor == Array); // true

因此,这足以满足大多数需求。那就是…

注意事项

将无法正常工作 在所有 在许多情况下,

这种模式虽然很复杂,但却很常见:

function Thingy() {
}
Thingy.prototype = {
    method1: function() {
    },
    method2: function() {
    }
};

Objects通过构造的newThingy将具有constructor指向而Object不是的属性Thingy。因此,我们一开始就陷入困境;您根本无法信任constructor您无法控制的代码库。

多重继承

一个不那么明显的例子是使用多重继承:

function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a

事情现在无法正常运行,因为您可能希望它们:

var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true

因此,如果object您的测试的object设置不同,则可能会得到意外的结果prototype。在此讨论范围之外,还有其他解决方法。

constructor物业还有其他用途,其中一些很有趣,而其他则不是很多。目前,我们将不深入研究这些用途,因为它与本次讨论无关。

无法跨框架和跨窗口工作

使用.constructor进行类型检查时要检查从不同的未来对象的类型将打破window对象,说的iframe或弹出式窗口。这是因为constructor在每个“窗口”中每种核心类型都有不同的版本,即

iframe.contentWindow.Array === Array // false

使用instanceof运算符…

instanceof运营商正在测试的一个干净的方式object式为好,但有自己潜在的问题,就像constructor财产。

var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true

但是instanceof对于文字值无效(因为文字不是Objects

3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false

该文本需要被包裹在一个Object为了instanceof工作,例如

new Number(3) instanceof Number // true

.constructor检查对于文字是很好的,因为.方法调用隐式地将文字包装在它们各自的对象类型中

3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true

为什么两个点为3?因为Javascript将第一个点解释为小数点;)

无法跨框架和跨窗口工作

instanceof出于与constructor属性检查相同的原因,也无法在不同的窗口中工作。

使用name属性的constructor属性…

不工作 在所有 在许多情况下,

同样,见上文;constructor完全完全错误且无用是很常见的。

在<IE9中不起作用使用myObjectInstance.constructor.name将为您提供一个包含所constructor使用函数名称的字符串,但要遵守constructor前面提到的有关属性的警告。

对于IE9及更高版本,您可以进行monkey-patch in support::

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1] : "";
        },
        set: function(value) {}
    });
}

有关文章的更新版本。此功能是在文章发布三个月后添加的,这是本文作者Matthew Scharley推荐使用的版本。这种变化是受到注释的启发,这些注释指出了先前代码中的潜在陷阱。

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s([^(]{1,})\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1].trim() : "";
        },
        set: function(value) {}
    });
}

使用Object.prototype.toString

事实证明,正如本文所详述的那样,您可以使用Object.prototype.toString-的低级通用实现toString-获取所有内置类型的类型

Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]

可以编写一个简短的辅助函数,例如

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

删除残留物并获取类型名称

type('abc') // String

但是,它将Object为所有用户定义的类型返回。

给所有人的警告…

所有这些都面临一个潜在的问题,那就是有关对象的构造方法。以下是构建对象的各种方式以及不同类型检查方法将返回的值:

// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // true
(obj.constructor.name == "Foo");  // true

// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // false
(obj.constructor.name == "Foo");  // false


// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object);              // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == "");         // true


// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object);      // true
(obj instanceof Foo);         // true
(obj.constructor == Foo);     // true
(obj.constructor.name == ""); // true


// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object);            // true
(obj.constructor == Object);        // true
(obj.constructor.name == "Object"); // true

尽管这组示例中没有所有排列,但希望有足够的信息可以让您了解根据您的需求情况如何变得凌乱。不要假设任何事情,如果您不完全了解所要追求的目标,则可能会由于缺乏精妙之处而导致代码意外中断。

注意:

typeof运算符的讨论似乎是一个明显的遗漏,但object由于它非常简单,因此在帮助识别an
是否为给定类型方面确实没有用。了解在哪里typeof有用很重要,但是我目前不认为这与本次讨论非常相关。但我的思想是开放的。:)



 类似资料:
  • 问题内容: 我如何获得后续的密钥名称?例如,我要“ button1”和“ button2”? 我尝试使用,尽管这没有用。 问题答案: 如果您稍微修改一下措辞,则可能会更好地理解: 请注意,您要遍历对象的属性,并在每个后续周期中使用对每个对象的引用。 MSDN说到以下内容: 在循环的每次迭代之前,都会为变量分配对象的下一个属性名称或数组的下一个元素索引。然后,您可以在循环内的任何语句中使用它来引用对

  • 问题内容: 有什么解决方案来获取对象的函数名称? -没有有关或的信息。有可能得到其中之一吗? 问题答案: 获取对象的构造函数,然后检查其name属性。 返回“ myClass”。

  • 本文向大家介绍JavaScript 获取函数对象的名称,包括了JavaScript 获取函数对象的名称的使用技巧和注意事项,需要的朋友参考一下 示例 6 ES6: 关于MDN的说明。自2015年起,可以在nodejs和除IE之外的所有主要浏览器中使用。 5 ES5: 如果您有对该功能的引用,则可以执行以下操作:

  • 问题内容: 我创建了一个JavaScript对象,但是如何确定该对象的类呢? 我想要一些类似于Java的方法。 问题答案: JavaScript中没有Java的完全对应版本。通常,这是由于JavaScript是一种基于原型的语言,而不是Java是一种基于类的语言。 一些例子: 注意:如果使用Uglify编译代码,它将更改非全局类名。为了防止这种情况,Uglify有一个参数,可以使用gulp或gru

  • 是否可以在运行时使用TypeScript获取对象的类/类型名称?

  • 问题内容: 我知道该类的名称,说 “ MyClass”, 并且想检索该对象。 MyClass.class 供将来参考。有没有办法做到这一点? 我已经浏览了整个网络,但发现与之相关的大多数内容都与有关,我认为这不适合我的情况。我不想初始化一个类,而只是获取一个类对象以备将来使用。 编辑:关于此的第一个答案: 我已经检查了该方法,但我认为这也应该初始化该类。现在,我可以使用完整参数来调用它,并传递给第