我在学how to make OOP with JavaScript.它有接口概念吗(比如Java的interface
)?
所以我可以创造一个听众...
我在学how to make OOP with JavaScript.它有接口概念吗(比如Java的interface
)?
所以我可以创造一个听众...
没有"该类必须具有这些函数"的概念(即本身没有接口),因为:
相反,JavaScript使用的是所谓的duck typing.(如果它像鸭子一样走路,像鸭子一样呱呱叫,就JS而言,它就是鸭子.)如果您的对象有quack()、walk()和fly()方法,那么代码可以在任何它希望对象能够行走、呱呱和飞行的地方使用它,而不需要实现一些"可回避"的接口.接口正是代码使用的函数集(以及这些函数的返回值),通过duck输入,您可以免费获得这些函数.
这并不是说,如果你try 调用some_dog.quack()
,你的代码不会中途失败;你会得到一个打字错误.坦率地说,如果你让狗嘎嘎叫,你会遇到更大的问题;可以说,当你把所有的鸭子排成一行,不让狗和鸭子混在一起,除非你把它们当作普通动物对待时,鸭子打字效果最好.换句话说,即使界面是流动的,它仍然存在;把一只狗交给一开始就希望它呱呱叫、飞起来的代码,这通常是一个错误.
但是,如果您确定您做的是正确的事情,那么您可以在try 使用某个特定方法之前,通过测试是否存在该方法来绕过嘎嘎狗问题.像这样的东西
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)代码,请try 稍微不同的版本:
function can(obj, methodName)
{
return ((typeof obj[methodName]) == "function");
}
if (can(someObject, "quack"))
{
someObject.quack();
}