JavaScript是否有接口类型(例如Java的“接口”)?
我正在学习如何用JavaScript制作OOP。它有接口概念(如Java的)吗?interface
所以我将能够创建一个听众...
我正在学习如何用JavaScript制作OOP。它有接口概念(如Java的)吗?interface
所以我将能够创建一个听众...
没有“这个类必须具有这些函数”的概念(即,本身没有接口),因为:
相反,JavaScript使用所谓的鸭子类型。(如果它像鸭子一样走路,像鸭子一样嘎嘎叫,就JS所关心的,它就是一只鸭子。如果你的对象有 quack()、walk() 和 fly() 方法,代码可以在任何需要可以走路、嘎嘎和飞翔的对象的地方使用它,而不需要实现一些“Duckable”接口。该接口正是代码使用的函数集(以及这些函数的返回值),通过 duck 键入,您可以免费获得该函数。
现在,这并不是说你的代码不会在中途失败,如果你尝试调用;你会得到一个TypeError。坦率地说,如果你告诉狗嘎嘎叫,你有更大的问题;鸭子打字最好当你把所有的鸭子都排成一排,可以这么说,除非你把它们当作普通动物,否则不要让狗和鸭子混在一起。换句话说,即使界面是流动的,它仍然在那里;将狗传递给期望它首先嘎嘎作响并飞行的代码通常是一个错误。some_dog.quack()
但是,如果你确定你正在做正确的事情,你可以通过在尝试使用特定方法之前测试它的存在来解决庸医问题。类似的东西
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对象根本没有,在IE8中,它据称仅适用于主机对象(即DOM元素等)。如果兼容性是一个问题,则不能使用 .(我甚至不会提到IE6,因为它在中国以外的地方已经无关紧要了。.defineProperty
.defineProperty
另一个问题是,一些编码风格喜欢假设每个人都写了糟糕的代码,并禁止修改以防有人想盲目使用。如果您关心这一点,或者正在使用(IMO损坏的)代码,请尝试稍微不同的版本:Object.prototype
for...in
function can(obj, methodName)
{
return ((typeof obj[methodName]) == "function");
}
if (can(someObject, "quack"))
{
someObject.quack();
}
拿起一份Dustin Diaz的“JavaScript设计模式”。有几章专门介绍如何通过 Duck Typing 实现 JavaScript 接口。这也是一本不错的读物。但是不,没有语言原生实现的接口,你必须鸭子类型。
// example duck typing method
var hasMethods = function(obj /*, method list as strings */){
var i = 1, methodName;
while((methodName = arguments[i++])){
if(typeof obj[methodName] != 'function') {
return false;
}
}
return true;
}
// in your code
if(hasMethods(obj, 'quak', 'flapWings','waggle')) {
// IT'S A DUCK, do your duck thang
}