您的位置:首页 > Web前端 > JavaScript

o.m()的那点儿事

2013-10-13 14:57 316 查看
在面向对象的系统中,如果o.m(),结果是去查找和调用一个对象o的方法m。

在Java里面,那么就是在o以及o的父类中去查找m的具体实现,如果找不到那么是无法通过编译的。在机制和Java一样的编程语言里面,你无法为已有的类(比如内置类型string)调用一个不存在的方法,除非你创建一个包装类比如stringwapper,给这个类添加方法m,然后每次使用的时候用的都应该是stringwapper的实例。好处是有且仅有一种方法,不会感觉莫名其妙,很容易找到实现m的地方。坏处是各种wapper,和更复杂的对象相等的逻辑。

在Javascript里面,如果是o.m,那么就是在o的构造函数的prototype开始的prototype链里面查找这个函数。如果事先没有而你又这么调用的话,你可以随时的在o里面或者o的prototype链的任何对象上添加这个方法。很多JS的库使用这种方式在Object或者Function的prototype上添加了若干比较实用的方法。好处是很方便的修改现有的类,坏处是很方便的破坏现有的类;另外就是看起来有点儿莫名其妙,怎么就多了这些函数。

在Scala, C++里面,首先o.m会和Java一样的方式查找,如果找不到,会在可见的作用域查找符合条件的隐式转换。也就是在作用域内看看是否有个方式,它以o为参数,能构建出另外一个类型o',这个类型上实现了m方法。好处是试用的时候不用手动调用这个转换,看起来比较干净。坏处是除了调用的时候不需要wapper,还是要自己写和实现类型转换。另外就是看起来有点儿莫名其妙,怎么就多了这些函数。C#的LINQ的select, where API就是这样的方式添加到已有的集合类型上的,C#的这种机制被称为扩展函数。

还有的是在某些动态语言里面,比如ruby和python,对于属性查找如果找不到,那么可能触发某些函数调用,比如method_missing。这个时候m会以字符串的方式传递进来,那么就可以在这里实现m的逻辑。好处是可以实现类似rails activerecord很方便,缺点是看起来很精妙理解有点儿费劲,还有可能的是性能损失。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息