我正在学习如何用JavaScript制作面向对象编程。是否有接口概念(如Java的接口)?

这样我就可以创建一个监听器。


当前回答

虽然javaScript中不像Java中那样有接口,但你可以用这条消息下的代码来模仿这种行为。因为接口基本上是一个强制契约,你可以自己构建它。

下面的代码来自3个类:接口、父类和子类。

接口中有检查方法和属性是否存在的方法。 父类用于使用Interface类在子类中强制执行所需的方法和属性。 孩子是父母规则强制执行的类别。

在您正确地设置它之后,如果子程序中缺少方法或属性,那么您将在控制台中看到一个错误,如果子程序正确地实现了契约,则什么也没有。

class Interface {  
    checkRequiredMethods(methodNames) {
        setTimeout( () => {
            const loopLength = methodNames.length;
            let i = 0
            for (i; i<loopLength; i++) {
                if (typeof this[methodNames[i]] === "undefined") {
                    this.throwMissingMethod(methodNames[i]);
                }

                else if (typeof this[methodNames[i]] !== "function") {
                    this.throwNotAMethod(methodNames[i]);
                }
            }
        }, 0);
    }

    checkRequiredProperties(propNames) {
        setTimeout( () => {
            const loopLength = propNames.length;
            let i = 0
            for (i; i<loopLength; i++) {
                if (typeof this[propNames[i]] === "undefined") {
                    this.throwMissingProperty(propNames[i]);
                }

                else if (typeof this[propNames[i]] === "function") {
                    this.throwPropertyIsMethod(propNames[i]);
                }
            }
        }, 0);     
    }

    throwMissingMethod(methodName) {
        throw new Error(`error method ${methodName} is undefined`);
    }

    throwNotAMethod(methodName) {
        throw new Error(`error method ${methodName} is not a method`);
    }

    throwMissingProperty(propName) {
        throw new Error(`error property ${propName} is not defined`);
    }

    throwPropertyIsMethod(propName) {
        throw new Error(`error property ${propName} is a method`);
    }
}
class Parent extends Interface {
    constructor() {
        super()

        this.checkRequiredProperties([
            "p1",
            "p2",
            "p3",
            "p4",
            "p5"
        ]);

        this.checkRequiredMethods([ 
            "m1",
            "m2",
            "m3",
            "m4"
        ]);
    }
}
class Child extends Parent {
    p1 = 0;
    p2 = "";
    p3 = false;
    p4 = [];
    p5 = {};

    constructor() {
        super();
    }

    m1() {}
    m2() {}
    m3() {}
    m4() {}
}
new Child()

其他回答

JavaScript (ECMAScript edition 3)有一个保留字以备将来使用。我认为这正是为了这个目的而设计的,然而,在匆忙发布规范的过程中,他们没有时间定义如何使用它,所以,目前,浏览器除了让它呆在那里,偶尔会抱怨你试图用它来做什么之外,什么也不做。

创建自己的object. implementation (Interface)方法是可能的,而且非常简单,只要在给定的对象中没有实现特定的属性/函数集,该方法的逻辑就会中断。

我写了一篇关于面向对象的文章,其中使用了我自己的符号如下:

// Create a 'Dog' class that inherits from 'Animal'
// and implements the 'Mammal' interface
var Dog = Object.extend(Animal, {
    constructor: function(name) {
        Dog.superClass.call(this, name);
    },
    bark: function() {
        alert('woof');
    }
}).implement(Mammal);

有很多方法来处理这个特殊的问题,但这是我在自己的接口实现中使用的逻辑。我发现我更喜欢这种方法,而且它易于阅读和使用(如上所述)。这意味着在Function中添加一个“实现”方法。原型,有些人可能有一个问题,但我发现它工作得很漂亮。

Function.prototype.implement = function() {
    // Loop through each interface passed in and then check 
    // that its members are implemented in the context object (this).
    for(var i = 0; i < arguments.length; i++) {
       // .. Check member's logic ..
    }
    // Remember to return the class being tested
    return this;
}

Js没有接口,但typescript有!

在Java中需要接口,因为它是静态类型的,并且在编译期间应该知道类之间的契约。在JavaScript中则不同。JavaScript是动态类型的;这意味着当你获得对象时,你可以检查它是否有特定的方法并调用它。

虽然javaScript中不像Java中那样有接口,但你可以用这条消息下的代码来模仿这种行为。因为接口基本上是一个强制契约,你可以自己构建它。

下面的代码来自3个类:接口、父类和子类。

接口中有检查方法和属性是否存在的方法。 父类用于使用Interface类在子类中强制执行所需的方法和属性。 孩子是父母规则强制执行的类别。

在您正确地设置它之后,如果子程序中缺少方法或属性,那么您将在控制台中看到一个错误,如果子程序正确地实现了契约,则什么也没有。

class Interface {  
    checkRequiredMethods(methodNames) {
        setTimeout( () => {
            const loopLength = methodNames.length;
            let i = 0
            for (i; i<loopLength; i++) {
                if (typeof this[methodNames[i]] === "undefined") {
                    this.throwMissingMethod(methodNames[i]);
                }

                else if (typeof this[methodNames[i]] !== "function") {
                    this.throwNotAMethod(methodNames[i]);
                }
            }
        }, 0);
    }

    checkRequiredProperties(propNames) {
        setTimeout( () => {
            const loopLength = propNames.length;
            let i = 0
            for (i; i<loopLength; i++) {
                if (typeof this[propNames[i]] === "undefined") {
                    this.throwMissingProperty(propNames[i]);
                }

                else if (typeof this[propNames[i]] === "function") {
                    this.throwPropertyIsMethod(propNames[i]);
                }
            }
        }, 0);     
    }

    throwMissingMethod(methodName) {
        throw new Error(`error method ${methodName} is undefined`);
    }

    throwNotAMethod(methodName) {
        throw new Error(`error method ${methodName} is not a method`);
    }

    throwMissingProperty(propName) {
        throw new Error(`error property ${propName} is not defined`);
    }

    throwPropertyIsMethod(propName) {
        throw new Error(`error property ${propName} is a method`);
    }
}
class Parent extends Interface {
    constructor() {
        super()

        this.checkRequiredProperties([
            "p1",
            "p2",
            "p3",
            "p4",
            "p5"
        ]);

        this.checkRequiredMethods([ 
            "m1",
            "m2",
            "m3",
            "m4"
        ]);
    }
}
class Child extends Parent {
    p1 = 0;
    p2 = "";
    p3 = false;
    p4 = [];
    p5 = {};

    constructor() {
        super();
    }

    m1() {}
    m2() {}
    m3() {}
    m4() {}
}
new Child()

Javascript没有接口。但它可以是鸭子类型的,一个例子可以在这里找到:

http://reinsbrain.blogspot.com/2008/10/interface-in-javascript.html