“多态”的字面意思就是”多种状态”,在OOP中意味着我们的代码可能要面临着多个分支。在日常编写Javascript时,我们也许会写出这样的条件选择语句:假设这里有两位赛跑选手runner1和runner2,我们要查看他们各自的跑步速度
var runner1 = new Object(); runner1.speed = 80; var runner2 = new Object(); runner2.speed = 100; function getSpeed(name){ if(name==='runner1') console.log(runner1.speed); if(name==='runner2') console.log(runner2.speed); } getSpeed('runner1');//80 getSpeed('runner2');//100
上面的语句就是多态的一种表现,但它仅仅代表了“多种状态”的意思,并没有把OOP中多态的关键体现出来。我们可以看到 if…else 判断分支语句,它把runner1和runner2分离开来,但这是很脆弱的。一旦我们要增加赛跑选手,那么,我们就必须创建一个新的runner3对象,设置他的速度属性value,并且而又最关键的是,我们必须把getSpeed函数内部添加分支语句,这就意味着getSpeed函数也需要进行更多的判断,运行成本增加。
多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事物”与 “可能改变的事物”分离开来。——《JavaScript设计模式与开发实践》
“多态”实际上是要把代码分离,是殊途同归,在尽力避免条件选择语句下,使得同一个操作函数(不变的部分)能够对不同的对象(会变的部分)执行同一个操作行为,并根据对象的不同,得出各自的结果。下面我们尝试建立赛跑选手(runner)的多态性,并消除选择分支语句。
var runner = new Function(); runner.prototype.speed = 0; var runner1 = new runner(); runner1.speed = 80; var runner2 = new runner(); runner2.speed = 120; function getSpeed(obj){ console.log(obj.speed); } getSpeed(runner1);// 80 getSpeed(runner2);// 120
可以看见,操作函数getSpeed非常简洁,内部并没有出现条件选择语句。如果我们要增加一个runner3,只需要创建一个runner的实例,并设置他的speed。(注意,这里把runner也分离开来,因为runner1,runner2…等等都是runner,这样以后我们要增加全体操作也会方便很多)。符合多态的代码具有生命力和拓展性,对于项目来说是有利的。
换句话说,多态最根本的作用就是通过把过程化的条件分支语句转化为对象的多态性。——《JavaScript设计模式与开发实践》