首页 技术 正文
技术 2022年11月9日
0 收藏 777 点赞 2,316 浏览 6520 个字

《JavaScript设计模式》笔记之第一、二章:富有表现力的JavaScript 和 接口


第一章

创建一个类

方法一:     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>

                   

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,494
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,295