如何获得JavaScript对象的类?

DNB*_*ims 665 javascript oop

我创建了一个JavaScript对象,但是我如何确定该对象的类?

我想要类似于Java的.getClass()方法.

ear*_*arl 930

getClass()JavaScript中没有与Java完全相同的东西.主要是因为JavaScript是基于原型的语言,而Java则是基于类的语言.

根据您的需要getClass(),JavaScript中有几个选项:

几个例子:

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

typeof Foo;             // == "function"
typeof foo;             // == "object"

foo instanceof Foo;     // == true
foo.constructor.name;   // == "Foo"
Foo.name                // == "Foo"    

Foo.prototype.isPrototypeOf(foo);   // == true

Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21);            // == 42
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用Uglify编译代码,它将更改非全局类名.为了防止这种情况,Uglify有一个--mangle可以设置为false的参数是使用gulpgrunt.

  • **警告**:如果你的代码被缩小,不要依赖`constructor.name`.函数名称将随意更改. (13认同)
  • ES5有一个'Object.getPrototypeOf()` (9认同)
  • 那应该是`func.prototype`(是的,函数是对象,但`prototype`属性只与函数对象有关). (6认同)
  • 你可能还想提一下`instanceof` /`isPrototypeOf()`和非标准`__proto__` (4认同)
  • @ igorsantos07,至少在2019年; 谷歌“在线javascript缩小器”的前5-10个结果中,将“ construction.name”识别为要忽略/不能最小化的令牌。除了大多数(如果不是全部),minifier软件还提供例外规则。 (2认同)

dev*_*os1 273

obj.constructor.name
Run Code Online (Sandbox Code Playgroud)

是现代浏览器中的可靠方法.Function.name被正式添加到ES6的标准中,使其成为符合标准的手段,将JavaScript对象的"类"作为字符串.如果对象被实例化var obj = new MyClass(),它将返回"MyClass".

它将为数字返回"Number",为数组返回"Array",为函数返回"Function"等.它通常按预期运行.它失败的唯一情况是如果创建的对象没有原型,通过Object.create( null ),或者对象是从匿名定义的(未命名的)函数实例化的.

另请注意,如果要缩小代码,则与硬编码类型字符串进行比较是不安全的.例如,而不是检查是否obj.constructor.name == "MyType",而不是检查obj.constructor.name == MyType.name.或者只是比较构造函数本身,但是这不会跨DOM边界工作,因为每个DOM上有不同的构造函数实例,因此在它们的构造函数上进行对象比较是行不通的.

链接原型时请注意

奇怪的是,Function.name返回原型链中使用的最基本函数的名称,遗憾的是这不是直观的.例如,如果var obj = new MyClass()从prototypically导出Object.create( null )和创建的新实例obj.constructor.name == "MyType",obj.constructor.name == MyType.name,Function.name返回"A",这似乎是错误的.然而,它确实适用于单级原型和所有原语.

  • **警告**:如果你的代码被缩小,不要依赖`constructor.name`.函数名称将随意更改. (24认同)
  • `obj.constructor.name`仅适用于_named_函数.即,如果我定义`var Foo = function(){}`,那么对于`var foo = new Foo()`,`foo.constructor.name`会给你空字符串. (13认同)
  • `Function.name`不是(但)JavaScript标准的一部分.它目前在Chrome和Firefox中受支持,但在IE(10)中则不受支持. (11认同)

Mak*_*dyk 33

我们可以通过执行“instance.constructor.name”来读取实例的类名称,如下例所示:

class Person {
  type = "developer";
}
let p = new Person();

p.constructor.name // Person
Run Code Online (Sandbox Code Playgroud)


Eli*_*rey 28

该函数返回"undefined","null"或者"class"[object class]Object.prototype.toString.call(someObject).

function getClass(obj) {
  if (typeof obj === "undefined")
    return "undefined";
  if (obj === null)
    return "null";
  return Object.prototype.toString.call(obj)
    .match(/^\[object\s(.*)\]$/)[1];
}

getClass("")   === "String";
getClass(true) === "Boolean";
getClass(0)    === "Number";
getClass([])   === "Array";
getClass({})   === "Object";
getClass(null) === "null";
// etc...
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于本机对象.如果你有某种继承,你总会得到"对象". (6认同)
  • 当然然后null和undefined将被取消选中,因为只有Object才有getClass方法 (2认同)

nop*_*ole 18

要获得"伪类",可以通过获取构造函数

obj.constructor
Run Code Online (Sandbox Code Playgroud)

假设在constructor执行继承时正确设置 - 这类似于:

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Run Code Online (Sandbox Code Playgroud)

和这两行,以及:

var woofie = new Dog()
Run Code Online (Sandbox Code Playgroud)

woofie.constructor指出Dog.注意,它Dog是一个构造函数,并且是一个Function对象.但你可以做到if (woofie.constructor === Dog) { ... }.

如果你想把类名作为字符串,我发现以下工作正常:

http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects

function getObjectClass(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(
            /function\s*(\w+)/);

        if (arr && arr.length == 2) {
            return arr[1];
        }
    }

    return undefined;
}
Run Code Online (Sandbox Code Playgroud)

它获取构造函数,将其转换为字符串,并提取构造函数的名称.

请注意,obj.constructor.name本来可以运作良好,但它不是标准的.它在Chrome和Firefox上,但不在IE上,包括IE 9或IE 10 RTM.


CMS*_*CMS 12

您可以使用构造函数属性获取对创建该对象的构造函数的引用:

function MyObject(){
}

var obj = new MyObject();
obj.constructor; // MyObject
Run Code Online (Sandbox Code Playgroud)

如果需要在运行时确认对象的类型,可以使用instanceof运算符:

obj instanceof MyObject // true
Run Code Online (Sandbox Code Playgroud)


mti*_*ani 7

我现在有一种情况可以通用工作,并使用了以下方法:

class Test {
  // your class definition
}

nameByType = function(type){
  return type.prototype["constructor"]["name"];
};

console.log(nameByType(Test));
Run Code Online (Sandbox Code Playgroud)

如果您没有对象的实例,那就是我发现通过类型输入获取类名称的唯一方法。

(用ES2017编写)

点符号也可以

console.log(Test.prototype.constructor.name); // returns "Test" 
Run Code Online (Sandbox Code Playgroud)


Hug*_*eth 6

对于 ES6 中的 Javascript 类,您可以使用object.constructor. 在下面的示例类中,该getClass()方法如您所料返回 ES6 类:

var Cat = class {

    meow() {

        console.log("meow!");

    }

    getClass() {

        return this.constructor;

    }

}

var fluffy = new Cat();

...

var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();

ruffles.meow();    // "meow!"
Run Code Online (Sandbox Code Playgroud)

如果您从getClass方法实例化类,请确保将其包装在括号中,例如ruffles = new ( fluffy.getClass() )( args... );


jam*_*ack 6

为了保持其向后兼容的不间断记录ECMAScript 6,JavaScript仍然没有class类型(尽管不是每个人都理解这一点)。它确实在创建原型时将class关键字作为其class语法的一部分,但仍然没有一个叫做class的东西。JavaScript现在不是,并且从来都不是经典的OOP语言。从类的角度讲JS只是一种误导,或者是尚未取消原型继承的迹象(只是保持它的真实性)。

这意味着this.constructor仍然是引用该constructor函数的好方法。并且this.constructor.prototype是访问原型本身的方法。由于这不是Java,所以它不是类。这是实例从中实例化的原型对象。这是一个使用ES6语法糖创建原型链的示例:

class Foo {
  get foo () {
    console.info(this.constructor, this.constructor.name)
    return 'foo'
  }
}

class Bar extends Foo {
  get foo () {
    console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
    console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))

    return `${super.foo} + bar`
  }
}

const bar = new Bar()
console.dir(bar.foo)
Run Code Online (Sandbox Code Playgroud)

这是使用babel-node以下命令输出的内容:

> $ babel-node ./foo.js                                                                                                                   ? 6.2.0 [±master ?]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'
Run Code Online (Sandbox Code Playgroud)

你有它!在2016年,classJavaScript中有一个关键字,但仍然没有类类型。this.constructor是获取构造函数this.constructor.prototype的最佳方法,也是访问原型本身的最佳方法。


Yan*_* Bo 6

不要使用o.constructor,因为它可以被对象内容更改。相反,使用Object.getPrototypeOf()?.constructor.

const fakedArray = JSON.parse('{ "constructor": { "name": "Array" } }');

// returns 'Array', which is faked.
fakedArray.constructor.name;

// returns 'Object' as expected
Object.getPrototypeOf(fakedArray)?.constructor?.name;
Run Code Online (Sandbox Code Playgroud)


Ale*_*nov 5

如果您不仅需要 GET 类,还需要从只有一个实例的角度扩展它,请编写:

让我们

 class A{ 
   constructor(name){ 
     this.name = name
   }
 };

 const a1 = new A('hello a1');
Run Code Online (Sandbox Code Playgroud)

因此,要扩展 A 仅使用实例:

const a2 = new (Object.getPrototypeOf(a1)).constructor('hello from a2')
// the analog of const a2 = new A()

console.log(a2.name)//'hello from a2'
Run Code Online (Sandbox Code Playgroud)