JavaScript中的接口是否必要?

时间:2009-09-14 04:04:06

标签: javascript oop interface dynamic-languages

我想这可能适用于任何动态语言,但我使用的是JavaScript。我们有一种情况,我们在JavaScript中编写了一些需要公开Send()函数的控件,然后由承载JavaScript的页面调用该函数。我们有一个定义了这个Send函数的对象数组,所以我们遍历集合并在每个对象上调用Send()。

在OO语言中,如果你想做类似的事情,你会有一个IControl接口,它有一个必须由每个控件实现的Send()函数,然后你有一个IControl实现的集合,你迭代并调用send方法。

我的问题是,JavaScript是一种动态语言,是否需要定义控件应该继承的接口,还是只需要调用控件上公开的Send()函数就足够了?

5 个答案:

答案 0 :(得分:10)

动态语言通常鼓励Duck Typing,其中对象的方法决定了它应该如何使用而不是明确的契约(例如接口)。

答案 1 :(得分:4)

由于您可以使用动态语言调用任何对象上的任何方法,因此我不确定接口如何以任何真正有用的方式发挥作用。没有合同要强制执行,因为一切都是在调用时确定的 - 一个对象甚至可以改变它是否符合“契约”的生命,因为在整个运行时添加和删除方法。如果对象没有履行合同,则调用将失败;如果没有实现成员,则调用将失败 - 对于大多数实际目的而言,这两种情况都是相同的。

答案 2 :(得分:3)

这与PHP相同;你真的不需要接口。但它们存在于建筑需求中。在PHP中,您可以为可能有用的函数指定类型提示。

其次,界面是合同。这是一个正式的合同,来自此界面的所有对象都具有这些功能。最好确保您的课程满足这些要求而不是记住:“ mm,此课程有isEnabled()但另一个课程为checkIfEnabled() ”。接口可帮助您实现标准化。处理派生对象的其他人不必检查名称是isEnabled还是checkIfEnabled(更好地让解释器捕获这些问题)。

答案 3 :(得分:2)

我们在下面的页面中看到了一个很好的实现,这是我们的(它的简短版本)

var Interface = function (methods) {
    var self = this;
    self.methods = [];

    for (var i = 0, len = methods.length; i < len; i++) {
        self.methods.push(methods[i]);
    }

    this.implementedBy = function (object) {

        for (var j = 0, methodsLen = self.methods.length; j < methodsLen; j++) {
            var method = self.methods[j];
            if (!object[method] || typeof object[method] !== 'function') {
                return false;
            }
        }
        return true;
    }
};

//Call
var IWorkflow = new Interface(['start', 'getSteps', 'end']);
if (IWorkflow.implementedBy(currentWorkFlow)) {
    currentWorkFlow.start(model);
}

整个例子是: http://www.javascriptbank.com/how-implement-interfaces-in-javascript.html

答案 4 :(得分:0)

bob.js提供了接口的另一种替代方法:

<强> 1。检查界面是否已实施:

var iFace = { say: function () { }, write: function () { } };  
var obj1 = { say: function() { }, write: function () { }, read: function () { } }; 
var obj2 = { say: function () { }, read: function () { } }; 
console.log('1: ' + bob.obj.canExtractInterface(obj1, iFace)); 
console.log('2: ' + bob.obj.canExtractInterface(obj2, iFace)); 
// Output: 
// 1: true 
// 2: false 

<强> 2。从对象中提取接口并仍然正确执行这些功能:

var obj = {  
    msgCount: 0, 
    say: function (msg) { console.log(++this.msgCount + ': ' + msg); }, 
    sum: function (a, b) { console.log(a + b); } 
}; 
var iFace = { say: function () { } }; 
obj = bob.obj.extractInterface(obj, iFace); 
obj.say('Hello!'); 
obj.say('How is your day?'); 
obj.say('Good bye!'); 
// Output: 
// 1: Hello! 
// 2: How is your day? 
// 3: Good bye!