让js具有面向对象的特性
来源:互联网 发布:离线阅读小说软件 编辑:程序博客网 时间:2024/06/06 00:36
需求分析:使用javascript时,难免会用到复杂的数据结构,当通过定义对象和方法无法解决问题时,就要考虑使用面向对象的方法
困难:js不支持类的定义,也就是说我们无法通过定义一个类来封装我们想要的属性和方法,可以直接定义一个对象而无需构造函数.
变通:对象中可以任意存放属性和方法,那么就可以使用对象来模拟出类
在使用js的时候,想必大家都是用过类似于以下形式的方式来为设置对象:
var myObj={};myObj.key = "value";myObj.func = function(key,value){myObj.key = value;}以上代码我们就定义了一个对象myObj,并且为其定义了一个属性key值为value,定义了一个方法function,然后我们可以做一下测试:
myObj.func("key","value2");alert(myObj.key);
结果是什么呢?value2
可以看到我们成功定义了一个对象的属性和方法,并通过方法修改了对象的属性.但这里有一个很大的缺点,这个对象只能"自我陶醉",无法像如果需要另外定义一个对象,赋予相同的属性和方法,就需要重复以上的步骤.而面向对象中,类和对象的区别就在于,类是对象的模板,可以使用构造方法来定义一系列具有相同属性和方法的对象.那么模仿面向对象,我们作如下改进:
function myObj(key,value){this.key = key;this.value = value;this.func = function(key){if(this.key ==key ){return this.value;}else{return null;}}}该方式是基于定义方法的模式来模拟一个类,那么该如何来使用呢?
var obj = new myObj("key","value");alert(obj.func("key"));看一看是不是特别像java里面的,定义一个类,然后使用构造方法定义对象,之后调用get方法返回value;
在这里有必要说一下:myObj相当于类名,myObj(key,value)相当于构造方法,只是融为一体了.使用this修饰的属性或方法都是public类型的,定义完以后可以通过对象访问.
如果需要定义私有的属性,可以使用var来修饰.
这个方法是我目前最常用的方式.
然而如果想要使用更多的面向对象的特性,比如继承,多态,可以用更好的办法来定义类.
使用"构造函数法"最大的问题是创建对象时需要用new来创建,这样的方式虽然好用,却是一种浪费内存的行为,也就是说,每创建一个对象,所有的属性和方法都会重新分配内存,其实使用js模拟类时毕竟不是真正的类,有些属性和方法都可以是公用的,这让我们想到了java的单例模式和静态变量.
javascript规定,所有的构造函数都有一个属性,prototype指向另一个对象,该对象下的所有属性和方法都会被构造函数继承,也就是说所有的static 的属性和方法我们可以定义在prototype上面,例如:
function myObj(key,value){this.key = key;this.value = value;this.func = function(key){if(this.key ==key ){return this.value;}else{return null;}}}myObj.prototype.type = "staticType";myObj.prototype.get = function(){}
这样无论创建多少个对象,他们拥有的属性type和方法get都是共享的了。
使用this和prototype时会把代码的结构搞的有些混乱,那些对js不是非常熟练的同学们就无法读懂和使用这些代码,那么怎么样进行改进让我们更易使用呢?
这里推荐一种极简主义方法,也就是抛弃this和prototype关键字,模仿单例模式创建对象。
例如:要创建一个Animal类:
var Animal={ getInstance:function(){var animal = {};animal.name="凯特";animal.run = function(){alert("100km/h");}; return animal; }};
原理很简单,对象里面定义了一个方法属性getInstance,该方法就是我们在java中常见的单例模式,也可以理解为工厂模式。如果想要创建对象,就去调用构造方法:
var a = Animal.getInstance();a.run();Animal跟类十分相似吧,getInstance就是个静态方法。
面向对象封装性已经说过了,以下说一说继承
再定义一个类(对象):
var Cat = { getInstance:function(){var cat= Animal.getInstance();cat.name="kite";cat.catchMouse = function(){ alert("can do");}; return cat; }};类Cat拥有一个相同的构造方法getInstance,只是Cat创建对象的时候是用Animal为模板创建的,再加上自己的属性和方法,就实现了继承,测试一下:
var cat1 = Cat.getInstance();cat1.run();cat1.catchMouse();可以证明,我们确实可以调用run()和catchMouse()也就是说继承的问题得到解决了,那么多态呢?子类是否能够覆盖父类的方法呢,子类的属性能否重写父类的属性呢?
继续测试:
alert(cat1.name);可以得出结论,cat1.name的值已经被替换了,至于方法当然也是这般。下面我们需要考虑一个问题,如何获得共享的属性,就像Java里面的static属性一样(java中的static变量属于类变量,不提倡通过对象调用,但可以调用,所有的对象调用都是同一状态),我们该怎么做呢?
var Cat = {legNum:4, getInstance:function(){var cat= Animal.getInstance();cat.name="kite";cat.catchMouse = function(){ alert("can do");}; cat.getLegNum = function(){cat.legNum = Cat.legNum;}cat.changeLegNum = function(legNum){Cat.legNum = legNum;}return cat; }};
测试一下legNum属性是不是共享的:
var cat1 = Cat.getInstance();var cat2 = Cat.getInstance();alert(cat1.getLegNum()==cat2.getLegNum());cat1.changeLegNum(3);alert(cat1.getLegNum()==cat2.getLegNum());可以看到两次打印出来的结果都是true,数据已经实现了共享,要注意,共享变量时依附于类的,在实现数据共享的过程中,要获得类的变量,修改变量也是最终实现类变量的修改。
- 让js具有面向对象的特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- prototype.js 让你更深入的了解javascript的面向对象特性
- Ext js面向对象的特性
- 关于js面向对象特性的理解
- 面向对象具有哪些特性以及对这些特性的理解
- Ext.js 面向对象特性
- 面向对象的特性
- 面向对象的特性
- 面向对象的特性
- 面向对象的特性
- 面向对象的特性
- prototype.js 深入学习 javascript 的面向对象特性
- spring中session管理
- centos6.4 安装 mysql5.5 confilt冲突 mysql5.1 lib 解决
- Codeforces Round #274 (Div. 2) B
- SSD7数据库系统实验Exercise2答案
- C++ 60分钟入门教程 - 2、C++与C语言的区别
- 让js具有面向对象的特性
- while中使用List.iterator().hasNext()为什么会出现无限循环
- 《实例妙解 Cocos2d-x 游戏开发》反馈勘误
- 在omnet++上仿真无线传感网络1
- ORCL基础总结
- JSP向后台传值以及hibernate向数据库传值的时候,中文乱码的问题
- 也来谈谈函数返回引用 int& fun(int &x);
- 读《乌合之众---第一章(群体的一般特征)》
- 推荐HTTP方式的OpenAPI的调试、测试工具:HttpRequester