测试某些东西是否是javascript中的类

时间:2009-02-08 22:44:09

标签: javascript

嘿所有,我试图测试传递给我的函数的参数是否是类名,以便我可以使用instanceof将它与其他类进行比较。

例如:

function foo(class1, class2) {
  // Test to see if the parameter is a class.
  if(class1 is a class)
  {
    //do some kind of class comparison.
    if(class2 is a class)
    {
       if(class1 instanceof class2)
       {
          //...
       }
    }
    else
    {
       //...
    }
  }
  else
    //...
}

这可能吗?我在google答案时遇到了麻烦。

8 个答案:

答案 0 :(得分:16)

javascript中确实没有“类”这样的东西 - 除了原语之外的一切都是对象。甚至函数都是对象。

instanceof DOES可以使用函数。看看这个link

function Car(make, model, year)
{
  this.make = make;
  this.model = model;
  this.year = year;
}
var mycar = new Car("Honda", "Accord", 1998);
var a = mycar instanceof Car;    // returns true
var b = mycar instanceof Object; // returns true

答案 1 :(得分:7)

现在我们有ES6的原生实现,有“真正的类”。与构造函数一样,这些主要用于原型继承的语法糖,但存在细微差别,两者不完全可互换。

到目前为止,我找到的唯一方法是获取对象的原型的构造函数的.toString(),并检查它是否以class开头或者如果对象有构造函数和{{ 的1}}以.toString()开头。

请注意,如果您的代码已编译(即:大多数Babel或TypeScript设置),那么这将在运行时返回class而不是function...(因为类被转换为构造函数)。

class...

这仅适用于已针对尚未转换为function isClass(obj) { const isCtorClass = obj.constructor && obj.constructor.toString().substring(0, 5) === 'class' if(obj.prototype === undefined) { return isCtorClass } const isPrototypeCtorClass = obj.prototype.constructor && obj.prototype.constructor.toString && obj.prototype.constructor.toString().substring(0, 5) === 'class' return isCtorClass || isPrototypeCtorClass } 的代码实施class的原生环境(Chrome,Firefox,Edge,node.js等)。

用法:

function

如果有更好的方法,我很想知道它是什么。

答案 2 :(得分:4)

JavaScript没有类。它具有与new一起使用时可用于生成对象实例的函数。因此,您真的想测试class2是否为函数。有很多方法可以实现这一目标; jQuery中isFunction()的当前(1.3)实现如下所示:

isFunction: function( obj ) {
    return toString.call(obj) === "[object Function]";
},

...但是请看这里有不同方法的概述: Best method of testing for a function in JavaScript?

答案 3 :(得分:2)

这是确定您是否具有类或函数的快速而肮脏的方法。

function myFunc() { };
Class MyClass() { };

Object.getOwnPropertyNames(myFunc);
// -> [ 'length', 'name', 'arguments', 'caller', 'prototype' ]

Object.getOwnPropertyNames(MyClass);
// -> [ 'length', 'prototype', 'name' ]

因此,如果arguments是属性名称,我们知道我们有一个函数,而不是一个类:

Object.getOwnPropertyNames(myFunc).includes('arguments');
// -> true

Object.getOwnPropertyNames(MyClass).includes('arguments');
// -> false

答案 4 :(得分:1)

我知道在函数上使用constructor.name会返回“ Function”,但在ES6类上这样做会返回类的名称。

我确实这样使用它:

function isClass(item){
 return item.constructor.name !== "Function" && item.constructor.name !== "Object";
}
class A {}
function B(){}
const aClass = new A();
const bFunction = B;
console.log(aClass.constructor.name); /*Will return "A"*/
console.log(bFunction.constructor.name); /*Will return "Function"*/
console.log("is aClass a class: ", isClass(aClass)); /*true*/
console.log("is bFunction a class: ", isClass(bFunction)); /*false*/

在我使用的情况下,这种方法效果很好。

希望这会有所帮助:)。

答案 5 :(得分:0)

我还没有找到100%确定的某种方法 如果某物是一个类而不是一个函数。的 在大多数情况下,上面接受的答案都可以,但是 有人重新定义了他们的方法toString() 在这种情况下可能会中断。他们为什么要 曾经重新定义过toString()吗?我不知道,问他们 如果他们仍然在附近:-)

所以我改为采用定义此方法 功能:

function isClass(v)
{ if (typeof v !== "function")
  { return false;
  }
  if ( typeof v.isClass === "function" &&
       v.isClass()
     )
  { return true;
  }
}

这意味着我可以将自己的课程标记为 是我认识的班级 给他们静态方法isClass() 返回true。如果有这样的课程 子类子类继承 方法并因此被自动识别 以及“班级”。

如果我需要与他人的 没有此方法的类 我可以先把他们的班级子类 我的子类就像他们的类 除了它还有isClass()方法。

我希望EcmaScript的下一个版本能够 纠正这种缺乏标准化解决方案的问题 但目前这是我能做的最好的。

它可能带来额外的好处 实际上给某些方法isClass() 我的非类函数也是 没有适当的课程,然后能够 将此类功能视为类, 无论出于何种原因,我都想这么做。

答案 6 :(得分:0)

我发现这很适合我。

if(typeof type === 'function' && type.name !== 'Object'){
   // This is a class.
}

我使用Typescript,并且能够使用它来一致地过滤类。

答案 7 :(得分:0)

我的解决方案是检查函数原型是否具有celery_1 | -------------- celery@3504f0d9bb2e v4.3.1 (rhubarb) celery_1 | ---- **** ----- celery_1 | --- * *** * -- Linux-4.19.121-linuxkit-x86_64-with-debian-9.7 2021-02-09 12:14:41 celery_1 | -- * - **** --- celery_1 | - ** ---------- [config] celery_1 | - ** ---------- .> app: app:0x7f82527f04a8 celery_1 | - ** ---------- .> transport: redis://redis:6379// celery_1 | - ** ---------- .> results: redis://redis:6379/ celery_1 | - *** --- * --- .> concurrency: 30 (prefork) celery_1 | -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) celery_1 | --- ***** ----- celery_1 | -------------- [queues] celery_1 | .> celery exchange=celery(direct) key=celery celery_1 | celery_1 | celery_1 | [tasks] celery_1 | . app_settings.tasks.import_meraki_templates celery_1 | . celery.accumulate celery_1 | . celery.backend_cleanup celery_1 | . celery.chain celery_1 | . celery.chord celery_1 | . celery.chord_unlock celery_1 | . celery.chunks celery_1 | . celery.group celery_1 | . celery.map celery_1 | . celery.starmap celery_1 | . app.celery.debug_task celery_1 | . monitoring.tasks.link_checks celery_1 | . monitoring.tasks.service_checks 以外的属性,并检查函数原型是否为constructor

该解决方案即使在使用 babel 转译后也可以工作,或者脚本以“use strict”运行。但是这种解决方案只有在类至少有一个公共函数或扩展其他类时才有效。

Function.prototype