Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测试某个东西是否是javascript中的类_Javascript - Fatal编程技术网

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

测试某个东西是否是javascript中的类,javascript,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 insta

嘿,我正在尝试测试传入函数的参数是否是类名,以便使用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
    //...
}

这可能吗?我在谷歌搜索答案时遇到了麻烦

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

isFunction: function( obj ) {
    return toString.call(obj) === "[object Function]";
},
function isAClassInstance(item){
 return item.constructor.name !== "Function" && item.constructor.name !== "Object";
}

class A {};
function B(){};
const aInstanceClass = new A();
const bFunctionInstance = new B();
const bFunction = B;
const aClass = A;
console.log(aInstanceClass.constructor.name); /*Will return "A"*/
console.log(bFunctionInstance.constructor.name); /*Will return "B"*/
console.log(A.constructor.name); /*Will return "Function"*/
console.log(B.constructor.name); /*Will return "Function"*/
console.log(bFunction.constructor.name); /*Will return "Function"*/
console.log("is A a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is B a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is aInstanceClass a class: ", isAClassInstance(aInstanceClass)); /*true*/
console.log("is bFunction a class: ", isAClassInstance(bFunction)); /*false*/
console.log("is bFunctionInstance a class: ", isAClassInstance(bFunctionInstance)); /*true*/
…但请参见此处了解不同方法的详细信息:
在javascript中确实没有“类”这样的东西——除了原语以外的所有东西都是对象。甚至函数也是对象

instanceof确实与函数一起工作。看看这个


现在我们有了ES6的本机实现,有了“真正的类”。这些基本上是原型继承的语法糖分,就像构造函数一样,但它们之间存在细微的差异,并且两者不能完全互换

到目前为止,我找到的唯一方法是获取对象原型的构造函数的
.toString()
,并检查它是否以
类开始,或者对象是否有构造函数,其中的
.toString()
类开始

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

这只适用于本机环境(Chrome、Firefox、Edge、node.js等),这些环境已经为尚未传输到
函数的代码实现了

用法:

class A {}
class B extends A {}
isClass(A) // true
isClass(new A()) // true
isClass(B) // true
isClass(new B()) // true

function C() {}
isClass(C) // false
isClass(new C()) // false
isClass({}) // false
isClass(Date) // false
isClass(new Date()) // false

//These cases return 'true' but I'm not sure it's desired
isClass(Object.create(A)) // true    
const x = {}
Object.setPrototypeOf(x, A)
isClass(x) // true

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

这里有一个快速而肮脏的方法来确定您是否有一个类或函数

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
箭头函数和
aysnc
函数没有
参数
属性名或
原型
。更完整的示例可能如下所示(假设我们知道输入只能是函数或类):

函数isFunction(函数类){
const propertyNames=Object.getOwnPropertyNames(functorClass);
返回(!propertyNames.includes('prototype')| | propertyNames.includes('arguments'));
}
log('classisfunction?',isFunction(classa{}));
log('function isFunction?',isFunction(function(){}));
log('async function isFunction?',isFunction(async function(){}));

log('arrow function isFunction?',isFunction(()=>{}))我还没有找到任何百分之百确定的方法来解决这个问题 如果某个东西是类而不是函数。这个 上述公认答案在大多数情况下有效,但如果 有人重新定义了他们的 在那种情况下,它可能会破裂。他们为什么要这样做 是否重新定义了toString()?我不知道,问问他们 如果它们仍然存在:-)

因此,我采取了定义这个的方法 功能:

function isClass(v)
{ if (typeof v !== "function")
  { return false;
  }
  if ( typeof v.isClass === "function" &&
       v.isClass()
     )
  { return true;
  }
}
这意味着我可以将自己的课程标记为 作为一个阶级,我把它看作是一个阶级 为他们提供静态方法isClass() 这是真的。如果此类课程有 子类子类继承 方法,从而自动识别 作为“班级”也是如此

如果我需要和别人一起工作 没有此方法的类 我可以先将他们的类划分为子类,这样 我的子类就像他们的类一样 除此之外,它还有isClass()方法

我希望EcmaScript的下一个版本能够 弥补这一标准化解决方案的不足 但现在这是我能做的最好的了

它还有我可能得到的额外好处 实际上,将方法isClass()提供给一些 还有我的非类函数,它们是 上课不适当,然后才能上课 将这些函数视为类,
无论出于什么原因,我都想这样做。

我觉得这对我很有用

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


我使用typescript,并且我能够使用它对类进行一致的筛选

我知道在函数上使用
constructor.name
将返回“function”,但在ES6类实例上这样做将返回类的名称

我确实是这样使用它的:

isFunction: function( obj ) {
    return toString.call(obj) === "[object Function]";
},
function isAClassInstance(item){
 return item.constructor.name !== "Function" && item.constructor.name !== "Object";
}

class A {};
function B(){};
const aInstanceClass = new A();
const bFunctionInstance = new B();
const bFunction = B;
const aClass = A;
console.log(aInstanceClass.constructor.name); /*Will return "A"*/
console.log(bFunctionInstance.constructor.name); /*Will return "B"*/
console.log(A.constructor.name); /*Will return "Function"*/
console.log(B.constructor.name); /*Will return "Function"*/
console.log(bFunction.constructor.name); /*Will return "Function"*/
console.log("is A a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is B a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is aInstanceClass a class: ", isAClassInstance(aInstanceClass)); /*true*/
console.log("is bFunction a class: ", isAClassInstance(bFunction)); /*false*/
console.log("is bFunctionInstance a class: ", isAClassInstance(bFunctionInstance)); /*true*/
对于我使用的案例来说,这非常有效

注意:由于类在技术上是一个函数,因此执行
new a()
new B()
的操作都是相同的,因此从isClassInstance返回相同的结果。 将函数与类区分开来的唯一方法是不要在函数上使用
new
,并将此关键字仅用于类


希望这会有所帮助:)。

我的解决方案是检查函数原型是否具有构造函数以外的属性,并检查函数原型是否为
函数。原型

此解决方案甚至在使用babel传输后也可以工作,或者脚本使用“use strict”运行。但是这个解决方案只有在这个类至少有一个公共函数或者扩展了另一个类的情况下才有效

函数类(func){
//类构造函数也是一个函数
if(!(func&&func.constructor==函数)| | func.prototype==未定义)
返回false;
//这是一个扩展其他类的类
if(Function.prototype!==Object.getPrototypeOf(func))
返回true;
//通常,函数在原型中只有“构造函数”
返回Object.getOwnPropertyNames(func.prototype).length>1;
}
//----举例----
等级水果{
hello(){}//必须至少有一个公共函数
}
//或者至少它扩展了其他类
梨类{}
console.log(isClass(Fruit));//真的
console.log(isClass(Pear));//真的
console.log(isClass(function(){}));//假的
log(isClass(函数(){“use strict”}));//假的
控制台
function isAClassInstance(item){
 return item.constructor.name !== "Function" && item.constructor.name !== "Object";
}

class A {};
function B(){};
const aInstanceClass = new A();
const bFunctionInstance = new B();
const bFunction = B;
const aClass = A;
console.log(aInstanceClass.constructor.name); /*Will return "A"*/
console.log(bFunctionInstance.constructor.name); /*Will return "B"*/
console.log(A.constructor.name); /*Will return "Function"*/
console.log(B.constructor.name); /*Will return "Function"*/
console.log(bFunction.constructor.name); /*Will return "Function"*/
console.log("is A a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is B a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is aInstanceClass a class: ", isAClassInstance(aInstanceClass)); /*true*/
console.log("is bFunction a class: ", isAClassInstance(bFunction)); /*false*/
console.log("is bFunctionInstance a class: ", isAClassInstance(bFunctionInstance)); /*true*/