第一章
创建一个类
方法一: var Anim = function() { … }; Anim.prototype.start = function() { … }; Anim.prototype.stop = function() { … };方法二: var Anim = function() { … }; Anim.prototype = { start: function() { … }, stop: function() { … } };方法三: Function.prototype.method = function(name, fn) { this.prototype[name] = fn; }; var Anim = function() { … }; Anim.method(‘start’, function() { … }); Anim.method(‘stop’, function() { … });方法四(在方法三上增加链式调用): 只需要在method方法上添加return this; Function.prototype.method = function(name, fn) { this.prototype[name] = fn; return this; };
第二章接口模仿
方法一:用注释描述接口/* interface Composite { function add(child); function remove(child); }*/ var CompositeForm = function(id, method, action) { //inplements Composite …}; //继承Composite接口 CompositeForm.prototype.add = function(child) { …};CompositeForm.prototype.remove = function(child) { …}; 缺点:主要利用注释来口头约束,要靠程序员自觉遵守优点:不需要额外的类或函数,简单方便
方法二:用属性检查模仿接口说明:在方法一中增加代码,主要是在需要继承某些接口的类中添加一个属性用于,告诉别人它有没有继承某些类,此外,再增加一个检查执行的函数,就可以方便的检查某个类是否继承了某些接口缺点: 如果程序员只是声明了自己有实现那个接口,但是没有实际实现,就会造成问题优点: 如果程序员正真按照约定,没在代码上说谎,那么就能有效的检测是否实现了接口例子:/*interface Composite { function add(child); function remove(child); function getChild(index);} interface FormItem() { function save();}*/ var CompositeForm = function(id,method,action) { this.implementsInterfaces = [‘Composite’, ‘FormItem’];//类中添加了这个属性,使对象说明自己是否实现了某些类 …} //检查对象是否自己有声称实现了某些接口function implements(object) { for(var i=1; i<arguments.length; i++) { var interfaceName = arguments[i]; var interfaceFound = false; for(var j=0; j<object.implementsInterfaces.length; j++) { if(object.implementsInterfaces[j] == interfaceName) { interfaceFound = true; break; } if(!interfaceFound) { return false; } return true;} // 使用例子function addForm(formInstance) { if(!implements(formInstance, ‘Composite’, ‘FormItem’)) { throw new Error(“没有实现某些接口”); } …}
方法三:鸭式辩型模仿接口例子:// 接口列表(个人理解:使用neInterface只是让别人知道这是一个接口定义,简单点可以直接用一个数组来代替)var Composite = new Interface(‘Composite’, [‘add’, ‘remove’, ‘getChild’]);var FormItem = new Interface(‘FormItem’, [‘save’]); //使用的时候通过一个定义好的函数ensureImplements来检查是否实现了接口ensureImplements(formInstance, Composite, FormItem); 说明: 这种方法的思想就是检测对象是否有与接口同名的方法
方法四:结合方法一和方法三的方法例子:// 接口列表var Composite = new Interface(‘Composite’, [‘add’, ‘remove’, ‘getChild’]);var FormItem = new Interface(‘FormItem’, [‘save’]); // 要实现上述接口的类var CompositeForm = function(id, method, action) { … // 实现Composit接口和FormItem接口}; function addForm(formInstance) { Interface.ensureImplements(formInstance, Composite, FormItem);}
Interface 类var Interface = function(name, methods) { if(arguments.length != 2) { throw new Error(“Interface constructor called with ” + arguments.length + “arguments, but expected exactly 2.”); } this.name = name; this.methods = []; for(var i = 0, len = methods.length; i< len; i++) { if(typeof methods[i] !== ‘string’) { throw new Error(“Interface constructor expects method names to be” + “passed in as a string.”); } this.methods.push(methods[i]); }}; // 验证实现的方法
12345678910111213141516171819 | Interface.ensureImplements = function (object) { if (arguments.length < 2) { throw new Error( "Interface.ensureImplements函数接收到的参数个数:" +arguments.length+ ",但是函数需要的参数个数为:2" ); } for ( var i = 1, len = arguments.length; i < len; i++) { var interface = arguments[i]; if (interface.constructor !== Interface) { throw new Error( "Interface.ensureImplements函数需要参数2以及后面的参数为Interface实例" ) } for ( var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) { var method = interface.methods[j]; if (!object[method] || typeof object[method] !== 'function' ) { throw new Error( "Interface.ensureImplements函数: 实例没有实现以下方法:" +interface.name); } } } }; |
综合例子:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 | <html> <body> <script> //Interface 类 var Interface = function (name, methods) { if (arguments.length != 2) { throw new Error( "Interface constructor called with " + arguments.length + "arguments, but expected exactly 2." ); } this .name = name; this .methods = []; for ( var i = 0, len = methods.length; i < len; i++) { if ( typeof methods[i] !== 'string' ) { throw new Error( "Interface constructor expects method names to be" + "passed in as a string." ); } this .methods.push(methods[i]); } }; Interface.ensureImplements = function (object) { if (arguments.length < 2) { throw new Error( "Interface.ensureImplements函数接收到的参数个数:" + arguments.length + ",但是函数需要的参数个数为:2" ); } for ( var i = 1, len = arguments.length; i < len; i++) { var interface = arguments[i]; if (interface.constructor !== Interface) { throw new Error( "Interface.ensureImplements函数需要参数2以及后面的参数为Interface实例" ) } for ( var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) { var method = interface.methods[j]; if (!object[method] || typeof object[method] !== 'function' ) { throw new Error( "Interface.ensureImplements函数: 实例没有实现以下方法:" + interface.name); } } } }; //定义了一个接口,接口需要有run方法和jump方法 var Animal = new Interface( 'Animal' ,[ 'run' , 'jump' ]); //实现Animal接口的Cat类 function Cat() {} Cat.prototype.run = function () {}; Cat.prototype.jump = function () {}; //实现Animal接口的Dog类 function Dog() {} Dog.prototype.run = function () {}; Dog.prototype.jump = function () {}; //没有实现Animal的Car类 function Car() {} Car.prototype.drive = function () {}; //有一只猫叫cat,有一只狗叫dog,有一部车叫car var cat = new Cat(); var dog = new Dog(); var car = new Car(); //假设一个人叫啊Mark,然后他很喜欢收养动物,今天他又来收养动物了。 var Mark = { adopt: function (animal) { Interface.ensureImplements(animal, Animal); console.log( "收养一只" +animal.constructor.name+ "成功" ); } }; Mark.adopt(cat); Mark.adopt(dog); Mark.adopt(car); </script> </body> </html> |