JavaScript 学习笔记 6 _接口和鸭子类型

然后是接口和“鸭子类型”

接口和“鸭子类型”

C++ 的虚类或者Java的接口为我们在代码中定义这些概念提供了必要的机制。接口在不同的软件组件之间定义了一个契约。接口提供了好的概念分离,并且支撑了很多的设计模式。

JavaScript没有正式的接口概念,那么我们如何来做呢?

最简单的方法是非正式地定义契约,并且在接口的每一端简单地依赖于开发者,明白他们正在做什么。Dave Thomas给中国方法起了一个迷人的名字“鸭子类型”(duck typing)——如果它走起来像鸭子,叫起来也像鸭子,那么它就是鸭子(这让我想起了中国的一句话叫啥来着)。

假设我们希望将两个形状的面积加在一起。在java中,我们可以编写:
public double addAreas(s1,s2)
{
return s1.getArea() + s2.getArea();
}

在JavaScript中:
function addAreas(s1,s2)
{
return s1.getArea() + s2.getArea();
}

有什么区别呢?恩,JavaScript参数没有类型约束,那么我们无法控制形状外的任何其他类型的传递,如果一个对象没有附加函数getArea(),我们将会得到一个JavaScript错误。

如何做呢?我们可以在调用它之前检查函数是否存在:

function has Area(obj)
{
return obj && obj.getArea && obj.getArea instanceof Function;
}

并且修改函数来使用这个检查:
function addAreas(s1,s2)
{
var total = null;
if(has Area(s1) && hasArea(s2))
{
total = s1.getArea() + s2.getArea();
}
return total;
}

我们可以编写一个通用的函数来检查对象是否有一个特定名称的函数,其实这里使用了JavaScript反射:
function implements(obj , funcName)
{
return obj && obj[funcName] && obj[funcName] instanceof Function;
}

再来一个同样作用的函数:
Object.prototype.implements = function(funcName)
{
return this && this[funcName] && this[funcName] instanceof Function;
}

注:第二个附加到了Object类的原型上,这就允许我们使用名称来检查特定的函数:
function has Area(obj)
{
return obj.implements(“getArea”);
}
还有特别的,可以测试对象是否遵守了一个完整的接口:
function isShape(obj)
{
return obj.implements(“getArea”) && obj.implements(“getPerimeter”);
}

到这里为止,我们发现这给我们带来了一定程度的安全性。但因为JavaScript函数没有预先定义的类型,所以无法知道JavaScript函数的返回值类型。

如何做来检查返回值类型呢?可以这样:
function isNum(arg)
{
return parseFloat(arg) != NaN; /*NaN是“非数”(not a number)的简写,是处理数字格式错误的一个特殊的JavaScript变量,parseFloat(“64djfjlkdsjf”)将会得到64 */
}

那么最后我们进一步来增强addAreas()函数:
function addAreas(s1,s2)
{
var total = null;
if(has Area(s1) && has Area(s2))
{
var a1 = s1.getArea();
var a2 = s2.getArea();
if(isNum(a1) && isNum(a2))
{
total = parseFloat(a1) + parseFloat(a2);
}
}
return total;
}

总结下:鸭子类型使事情保持简单,你不必去担心出现未知的错误,但是要求你相信开发团队能够明白所有的细节。随着一个人从单个作者或者小型联系紧密的团队转移到大型的(包括分散的小团队)项目中,这种信任会不可避免地削弱。


下一篇深入函数了哦~~~~嘿嘿~~~~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值