JavaScript模拟面向对象
2010-09-29 02:53
281 查看
JavaScript模拟面向对象
1. 类
2. 私有变量
3. 公共变量
4. 静态变量
5. 私有方法
6. 公共方法
7. 静态方法
8. JS 模式私有变量、方法、静态变量、方法、公共变量、方法完整的例子
9. 接口
接口使用的例子:
10. 继承
类式继承 – 原型链
类式继承 – extend函数
类式继承 – 对extend函数的改进
1. 类
//创建一个Person类 var Person= function(name,sex){ this._name = name; this._sex = sex; } //创建一个Person对象 var person = new Person(“狂奔”,’男’); |
var Person = function(name,sex){ this._name = name; this._sex = sex; var _age,_address; //私有变量 this.setAge = function(age){ this_age = age; } this.getAge = function(){ return _age; } ……. } |
//创建一个Person类 var Person= function(name,sex,age){ this._name = name; this._sex = sex; this.age = age; //公有变量 } Person.prototype = { country:’中国’, //公共变量 display:function(){ alert(this.country); } } |
var Person= function(name,sex,age){ this._name = name; this._sex = sex; Person.country = "中国"; } //调用静态变量 new Person(); alert(Person.country); |
var Person= function(name,sex){ this._name = name; this._sex = sex; //私有方法 var checkEmail = function(){ return true; } } |
var Person= function(name,sex){ this._name = name; this._sex = sex; } Person.prototype = { //公共方法 add:function(){ alert(“执行【添加】操作!”); } } //调用公共方法 new Person(“狂奔”,”男”).add(); |
var Person= function(name,sex){ this._name = name; this._sex = sex; Person.converToCase = function(_name){ alert("将["+_name+"]转换成大写!"); } } //调用静态方法 new Person(); Person.converToCase(“shangwu”); |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>JS 模式私有变量、方法、静态变量、方法、公共变量、方法完整的例子</title> <script type="text/javascript"> var Person = function(_name,_sex){ /********************************************************************************* * 私有属性 *********************************************************************************/ var age,address,phone,email; var checkPhone = function(){ return true; } var checkEmail = function(){ return true; } /********************************* 私有属性 end **********************************/ /********************************************************************************* * 这些属于特权方法,因为他们是公共方法,但可以访问私有属性及私有变量 *********************************************************************************/ //姓名 this.setName = function(_name){ name = _name || 'No name specified'; } this.getName = function(){ return name; } //性别 this.setSex = function(_sex){ sex = _sex || 'No sex specified'; } this.getSex = function(){ return sex; } //年龄 this.setAge = function(_age){ age = _age; // || 'No age specified'; } this.getAge = function(){ return age; } //地址 this.setAddress = function(_address){ address = _address || 'No address specified'; } this.getAddress = function(){ return address; } //电话 this.setPhone = function(_phone){ phone = _phone || 'No phone specified'; } this.getPhone = function(){ return phone; } //邮件 this.setEmail = function(_email){ if(!checkEmail(_email)) throw new Error('Book: Invalid ISBN'); email = _email || 'No email specified'; } this.getEmail = function(){ return email; } /****************************特权方法结束****************************************/ /********************************************************************************* * 静态变量、静态方法 *********************************************************************************/ Person.country = "中国"; Person.converToCase = function(_name){ alert("将["+_name+"]转换成大写!"); } /***********************************静态变量、静态方法 end************************/ /********************************************************************************* * 常量:是一些不能被修改的变量, * 在js中,可以通过创建只有取值器而没有赋值器的私有变量来模仿常量。 *********************************************************************************/ var Max = 154; Person.getMax = function(){ return Max; } //若要使用多个常量可以如下: var constants = {UPPER:100,LOWER:-100}; Person.getConstant = function(_name){ return constants[_name]; } /****************************** 常量 end *****************************************/ //构造方法设置属性 this.setName(_name); this.setSex(_sex); } /********************************************************************************* * 公共属性、方法,不可以访问私有变量、私有方法 *********************************************************************************/ Person.prototype = { display:function(){ var personInfo = "姓名:"+this.getName()+" 性别:"+this.getSex()+" 年龄:" +this.getAge()+" 地址:"+this.getAddress()+" 电子邮件:" + this.getEmail(); alert(personInfo); }, add:function(){ alert('执行[添加]操作!'); }, edit:function(){ alert('执行[编辑]操作!'); }, del:function(){ alert("执行[删除]操作!"); } }; //创建Person实例、设置实例方法、调用实例方法 var p = new Person('狂奔','男'); p.setAge(18); p.setAddress("深圳"); p.setEmail("shenzhen_zsw@163.com"); p.display(); p.add(); p.edit(); p.del(); //调用常量 alert(Person.getMax()); alert(Person.getConstant('LOWER')); //调用静态变量、静态方法 alert(Person.country); Person.converToCase(p.getName()); </script> </head> <body> </body> </html> |
/** * name:指的是接口名称 * methods:指的是接口中定义的方法如:["add","edit","del"] */ var Interface = function(name,methods){ if(arguments.length!=2){ throw new Error("接口构造函数包含" + arguments.length + "参数,但必须是是个!"); } this.name = name; this.methods = []; for(var i = 0, len = methods.length; i < len; i++){ if(typeof methods[i] !== 'string'){ throw new Error("结构构造函数中定义的方法名必须是字符串类型"); } this.methods.push(methods[i]); } }; Interface.ensureImplements = function(object){ if(arguments.length < 2){ throw new Error("Function Interface.ensureImplements called with " + arguments.length + "arguments,but expected at least 2."); } for(var i = 1,len = arguments.length; i<len; i++){ var interface = arguments[i]; if(interface.constructor !== Interface){ throw new Error("Function Interface.ensureImplements expects arguments two and above to be instances of 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("Function Interface.ensureImplements : object does not implement " +"the interface.name interface.Method" + method + " was not found."); } } } } |
var PiJiu = new Interface('PiJiu',['getDisplay']); var JinWei = function(){ this.name = "金威啤酒"; } JinWei.prototype = { getDisplay : function(){ return "你好,我是["+this.name+"]!"; } }; var QingDao = function(){ this.name = "青岛啤酒"; } QingDao.prototype = { getDisplay : function(){ return "你好,我是["+this.name+"]!"; } } var PinJiuFactory = function(pjObj){ Interface.ensureImplements(pjObj,PiJiu); this.pj = pjObj; } PinJiuFactory.prototype = { getPiJiu : function(){ var str = this.pj.getDisplay(); alert(str); } }; var qingDaoPJ = new QingDao(); var jinWeiPJ = new JinWei(); var testPj = new PinJiuFactory(qingDaoPJ); testPj.getPiJiu(); testPj = new PinJiuFactory(jinWeiPJ); testPj.getPiJiu(); |
类式继承 – 原型链
function Person(name){ this.name = name; } Person.prototype.getName = function(){ return this.name; } function Author(name,books){ Person.call(this,name); //调用父类的构造函数,并将name参数传给它 this.books = books; } /* 设置原型链,JavaScript中每个对象都有一个名为prototype的属性这个属性要么只想另一个对象,要么是null 为了让一个类继承另一个类,只是将子类的prototype设置为指向超类的一个实例。 为了让Author继承Person类,必须手工将Author的prototype属性设置为Person的一个实例。 最后一个步骤是将prototype的constructor属性设置为Person的实例时,其constructor属性被抹除了。 */ Author.prototype = new Person(); Author.prototype.constructor = Author; Author.prototype.getBooks = function(){ return this.books; } /* * 指的注意的是,在执行Person.call(this,name);这一步的时候我们已经把name * 这个属性拷贝到Person里面了,这里我们不在需要new Person()里面的这个null * 的name,所以直接把他们删除,免得浪费内存 */ delete Author.prototype.name; var author = new Author("闫宏","Java与模式"); alert(author.getName()); alert(author.getBooks()); |
/* 把派生子类的的整个过程包装在一个名为extend的函数中, 它的作用与其他语言中的extend函数类似, 即基于一个给定的类创建一个新对象的类。 实现步骤: 1.设置prototype 2.在将constructor重设置为恰当的值 3.做了一项改进,它添加了一个空函数F,并将用它创建一个对象的实例插入到原型链中。 这样做可以避免创建类的新实例,以为可能会比较庞大,而且有时超类的构造函数有一些副作用, 或者会执行一些需要进行大量计算的任务。 */ function extend(subClass,superClass){ var F = function(){}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; } /*----- extend函数的用法--------*/ function Person(_name){ this.name = _name; } Person.prototype.getName = function(){ return this.name; } function Author(_name,_books){ Person.call(this,_name); this.books = _books; } extend(Author,Person); Person.prototype.getBooks = function(){ return this.books; } var author = new Author("闫宏","Java与模式"); alert(author.getName()); alert(author.getBooks()); /* 在这里,不需要手工设置prototype和constructor属性, 而是通过在类声明之后(在向prototype添加任何方法之前)立即调用extend函数, 可以达到同样的目的。 不过还是有一个问题,超类的名称被固有化在子类的声明之中。 下面会对extend进行改进 */ |
/* * 在此记录中,他提供了superclass属性,这个属性可以用来用户子类与父类之间的耦合。 * 有了superclass属性,就可以直接调用父类超类中的方法。 * 如果既要重定义超类的某个方法而又想访问其在超类中的实现时可以派上用场) */ function extend(subClass,superClass){ var F = function(){}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; subClass.superclass = superClass.prototype; if(superClass.prototype.construtor == Object.prototype.constructor){ superClass.prototype.constructor = superClass; } } /*此函数的用法*/ function Person(_name){ this.name = _name; } Person.prototype.getName = function(){ return this.name; } function Author(_name,_books){ Author.superclass.constructor.call(this,_name); this.books = _books; } extend(Author,Person); Author.prototype.getBooks = function(){ return this.books; } var test = new Author("闫宏","Java与模式"); alert(test.getName()); alert(test.getBooks()); |
相关文章推荐
- javascript面向对象基础——作用域、闭包、模拟私有属性
- [原]Java程序员的JavaScript学习笔记(6——面向对象模拟)
- Java程序员的JavaScript学习笔记(6——面向对象模拟)
- JavaScript的面向对象
- JavaScript面向对象编写购物车功能
- JavaScript面向对象焦点图片轮播banner
- javascript面向对象思想
- javascript面向对象
- javascript面向对象程序设计
- 在JavaScript 自定义对象来模拟Java中的Map
- JavaScript面向对象
- javascript 面向对象特性与编程实现
- JavaScript 面向对象程序设计(上)——封装[转]
- javascript笔记3-面向对象的程序设计-创建对象
- javascript高级程序设计第三版 第六章 面向对象的程序设计
- JavaScript中的面向对象介绍
- javascript面向对象精华编程
- JavaScript面向对象学习总结(1.0)
- JavaScript 面向对象程序设计(上)——封装