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

JavaScript是否具有接口类型(例如Java的“接口”)?

徐栋
2023-03-14
问题内容

我正在学习如何使用JavaScript进行OOP。它具有接口概念(例如Java的接口interface)吗?

这样我就可以创建一个侦听器…


问题答案:

没有“此类必须具有这些功能”的概念(也就是说,本身没有接口),因为:

  1. JavaScript继承基于对象,而不是类。除非您意识到:这不是什么大不了的事情
  2. JavaScript是一种 非常 动态的类型化语言-您可以使用适当的方法创建对象,这将使其符合接口, 然后取消定义 使其符合要求的 所有内容 。颠覆类型系统非常容易-甚至偶然!-首先尝试创建类型系统是不值得的。

相反,JavaScript使用所谓的鸭子类型。(就JS而言,如果它像鸭子一样行走,而像鸭子一样嘎嘎叫,那就是鸭子。)如果对象具有quack(),walk()和fly()方法,则代码可以在期望的任何地方使用它一个可以走路,嘎嘎和飞起来的对象,而无需实现某些“可插入”接口。接口恰好是代码使用的一组函数(以及这些函数的返回值),通过鸭子输入,您可以免费获得它。

现在,这并不是说,如果您尝试调用,您的代码不会中途失败some_dog.quack()。您将收到TypeError。坦白说,如果您要让狗嘎嘎叫,那您的问题就会大一些。可以说,当您将所有鸭子连续放置时,鸭子打字最有效,除非您将它们视为普通动物,否则不要让它们混在一起。换句话说,即使界面是流畅的,它仍然存在。将狗传递给期望它一开始就发出嘎嘎叫声的代码通常是错误的。

但是,如果您确定自己做的正确,则可以在尝试使用特定方法之前测试是否存在特定方法,从而解决嘎嘎狗问题。就像是

if (typeof(someObject.quack) == "function")
{
    // This thing can quack
}

因此,您可以在使用前检查所有可以使用的方法。但是,语法有点丑陋。有一种更漂亮的方法:

Object.prototype.can = function(methodName)
{
     return ((typeof this[methodName]) == "function");
};

if (someObject.can("quack"))
{
    someObject.quack();
}

这是标准的JavaScript,因此可以在任何值得使用的JS解释器中使用。它具有像英语一样阅读的额外好处。

对于现代浏览器(即IE 6-8以外的几乎所有浏览器),甚至都可以通过以下方式阻止该属性显示for...in

Object.defineProperty(Object.prototype, 'can', {
    enumerable: false,
    value: function(method) {
        return (typeof this[method] === 'function');
    }
}

问题在于IE7对象根本没有.defineProperty,而在IE8中,据称它仅适用于宿主对象(即DOM元素等)。如果兼容性是一个问题,则不能使用.defineProperty。(我什至不提IE6,因为在中国以外它不再重要了。)

另一个问题是,某些编码风格喜欢假定每个人都编写错误的代码,并禁止修改Object.prototype以防有人想要盲目使用for...in。如果您对此有所关注,或者正在使用这样做的代码(IMO
损坏 ),请尝试稍有不同的版本:

function can(obj, methodName)
{
     return ((typeof obj[methodName]) == "function");
}

if (can(someObject, "quack"))
{
    someObject.quack();
}


 类似资料:
  • 问题内容: 目前我有这样的事情 main.go 还有我的工作包 和 我正在传递给NewJob的函数是在goroutine上每2秒执行一次,但是我想访问我传递的匿名结构…但是当我尝试访问时 编号 我越来越 t.Id未定义(类型interface {}是没有方法的接口) 但是打印t给我预期的结果 {1} 问题答案: 您必须先将其声明为兼容类型,然后才能访问其字段。

  • 问题内容: 我想在嵌套的静态接口中使用泛型类。我的目标是做这样的事情: 但是我得到一个错误:无法对非静态类型T进行静态引用。如果进行一些更改(如下所述),我可以在接口内部使用泛型,但是我想避免使用此方法,因为编写同一个类两次:一次用于MyClass,一次用于MyInterface。 谢谢。 编辑 :我想这样做: 要么 问题答案: 静态嵌套类或嵌套接口(顺便说一句,始终是静态的)与其外部类(或接口)

  • 为什么我不能这样做?我得到编译错误。 那是Java8 我不认为这里违反了任何OO原则。 这真的让我很难实现通用 API...... (我试图将泛型从游戏中剔除,因为泛型API变得反直觉了)

  • 问题内容: c#是否具有Java Runnable接口的等效项? 如果不能,那么如何实现?或者根本不需要? 谢谢。 问题答案: 不。C#处理线程的方式与Java不同。您不必创建Thread类的子类,而只是创建一个新的System.Threading.Thread对象,并向其传递ThreadStart委托(这是工作所在的函数)。

  • 我正在尝试返回一个对象,它应该是IClass的一个实现,具有一个通用类型,是IType的一个实现。 我要返回的实际类扩展了Class (abstract ),其泛型类型为ActualType: 抽象类对象实现了IClass接口,可以有任何扩展IType的类型 ActualType只是实现了IType接口 我在编译时得到一个“类型不匹配:无法从ActualClass转换为IClass”错误。我不明白

  • 7.2. 接口类型 接口类型具体描述了一系列方法的集合,一个实现了这些方法的具体类型是这个接口类型的实例。 io.Writer类型是用的最广泛的接口之一,因为它提供了所有的类型写入bytes的抽象,包括文件类型,内存缓冲区,网络链接,HTTP客户端,压缩工具,哈希等等。io包中定义了很多其它有用的接口类型。Reader可以代表任意可以读取bytes的类型,Closer可以是任意可以关闭的值,例如一