javascript - JavaScript 是否有接口(interface)类型(例如 Java 的 'interface' )?

标签 javascript oop

我正在学习 how to make OOP with JavaScript .有没有接口(interface)的概念(比如Java的interface)?

所以我可以创建一个监听器...

最佳答案

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

  1. JavaScript 继承基于对象,而不是类。在您意识到之前,这没什么大不了的:
  2. JavaScript 是一种非常动态类型的语言——你可以用适当的方法创建一个对象,这将使它符合接口(interface),然后取消定义所有的东西符合。颠覆类型系统非常容易——即使是偶然的! -- 一开始就尝试创建类型系统是不值得的。

相反,JavaScript 使用所谓的 duck typing . (如果它像鸭子一样走路,像鸭子一样嘎嘎叫,就 JS 而言,它就是一只鸭子。)如果你的对象有 quack()、walk() 和 fly() 方法,代码可以在任何它期望的地方使用它一个可以行走、嘎嘎和飞行的对象,不需要实现一些“Duckable”接口(interface)。接口(interface)正是代码使用的一组函数(以及这些函数的返回值),并且通过鸭子输入,您可以免费获得。

现在,这并不是说如果您尝试调用 some_dog.quack(); 您的代码不会在中途失败。你会得到一个 TypeError。坦率地说,如果你告诉狗嘎嘎,你的问题会稍微大一点。当您将所有鸭子排成一排时,鸭子打字效果最好,可以这么说,并且不让狗和鸭子混在一起,除非您将它们视为普通动物。换句话说,即使界面是流动的,它仍然存在;将狗传递给期望它首先会嘎嘎飞的代码通常是错误的。

但是,如果您确定自己在做正确的事情,则可以通过在尝试使用特定方法之前测试其是否存在来解决 quacking-dog 问题。类似的东西

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 broken) 代码,请尝试稍微不同的版本:

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

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

关于javascript - JavaScript 是否有接口(interface)类型(例如 Java 的 'interface' )?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3710275/

相关文章:

javascript - 两次播放后动态声音不播放

javascript - 如何制作 jQuery 输入字符串剪辑

python - Kivy.Clock,如何返回和访问从预定方法返回的变量?

objective-c - 包含文件时出错

c++ - 如何在 C++ 中访问动态分配的矩阵?

java - 访问客户端服务器设置中的对象

javascript - 如何简化 Q promise 示例

javascript - 将另一个文件中的 JS 对象提取到变量中

javascript - Angular 1 按钮而不是 3

java - 面向对象的Java : Better to extend a class or create a new instance of the subclass?