JavaScript与C++、Java等面向对象编程语言有本质的区别,然而就像不懂Linux人,会创造一个蹩脚的linux一样,一些JavaScript的编程者,总在尝试利用JavaScript 去模拟传统的面向对象编程。传统的面相对象编程是利用继承和多态两种机制实现代码的复用。继承的实质就是对父类的复制;多态是对父类方法的重写,当在调用这个方法时,会根据调用的情况选择合适的方法。
JavaScript 实现类的继承(即复制),使用混入机制:
1 function mixin(sourceObj,targetObj) 2 { 3 for (var key in sourceObj) 4 { 5 if(!(key in targetObj)) 6 { 7 targetObj[key] = sourceObj[key]; 8 } 9 } 10 }
ES6中为了实现类,新增加了关键字class,extends,super,用来实现传统的面向对象编程。然而,class语法并没有解决所有的问题,class基本上只是现在的prototype机制的一种语法糖。也就是说class并不会像传统的面向对象的语言一样,在声明时静态复制所有行为。如果你有意或者无意修改或者替换了父“类”中的一个方法,那子“类”和所有实例都会受到影响,因为它们在定义时并没有进行复制,只是使用基于prototype的实时委托。
其实JavaScript的原型链是一种很好的实现代码复用的机制,行为委托就是基于原型链的一种实现代码复用的机制。
Task = { setID:function (ID){ this.id = ID; }, outputID:function (){ console.log(this.id); } }; //让XYZ委托Task //XYZ = {}; //Object.setPrototypeOf(XYZ,Task); //让XYZ的__proto__指向Task。 XYZ = Object.create(Task); XYZ.prepareTask = function(ID,Label){ this.setID(ID); this.label = Label; }; XYZ.outputTaskDetails = function(){ this.outputID(); console.log(this.label); }