JavaScript之——面向对象
2016-11-13 21:31
204 查看
概述:
说起面向对象,我们最熟悉的一般是C#和JAVA,然而,关于JavaScript是不是一个面向对象的语言各有各的理解,刚才查了百科,JavaScript属于一个基于原型的面向对象,也就是JavaScript算是一个基于对象的编程语言,但是个人理解上,面向对象是一种编程思想,关于语言是不是面向对象的不必过于纠结,用的多了,自然有所理解,很多人包括我在内,其实基本上在用着JAVA这个面向对象的语言编着面向过程的程序;刚学习了JavaScript的面向对象编程思路,在这里整理一下自己的思路,是对自己学习的一个记录也是帮助初学者做一个入门认识。最初程序
起初我们创建对象的方式如下代码所示:var box = new Object(); //创建一个Object 对象 box.name = 'Lee'; //创建一个name 属性并赋值 box.age = 100; //创建一个age 属性并赋值 box.run = function () { //创建一个run()方法并返回值 return this.name + this.age + '运行中...'; }; alert(box.run()); //输出属性和方法的值
特点分析:创建一个全局的对象,分别做对象的属性和方法的初始化。
缺点分析:没有封装性,如果再创建一个一样的对象,需要再重新写一遍代码。代码量大,复用性差。
工厂模式
基于上边的缺点分析我们将上边的代码封装到一个函数中,来集中做对象的创建和初始化工作。代码如下:function createObject(name, age) { //集中实例化的函数 var obj = new Object(); obj.name = name; obj.age = age; obj.run = function () { return this.name + this.age + '运行中...'; }; return obj; } var box1 = createObject('Lee', 100); //第一个实例 var box2 = createObject('Jack', 200); //第二个实例 alert(box1.run()); alert(box2.run()); //保持独立
特点分析:通过一个函数将对象创建和初始化过程封装起来,最后将该对象返回。称这种方式为工厂模式。
缺点分析:对象实例无法区分,因为函数中返回的对象一溜都是Object类型。
构造函数
利用构造函数也可以用来创造特定的对象,代码如下:function Box(name, age) { //构造函数模式 this.name = name; this.age = age; this.run = function () { return this.name + this.age + '运行中...'; }; } var box1 = new Box('Lee', 100); //new Box()即可 var box2 = new Box('Jack', 200); alert(box1.run()); alert(box1 instanceof Box); //很清晰的识别他从属于Box
特点分析:通过构造函数不再在函数中new对象,并最后将对象返回,而是,直接在外部通过new构造函数生成对象,同时自动返回对象。
工厂模式和构造函数方式的区别:对比JAVA的编程过程可以理解,工厂模式纯粹就是一个方法,在该方法中创建一个对象,并最后将对象返回,而构造函数是一个特殊的方法,调用该方法会自动返回一个对象,返回对象的类型就是该方法名对应的类型。
缺点分析:上边的方法看起来已经算是完美了,但是,有个缺点就是函数中的run方法不是共享的,也就是说每new一个对象就会创建新的run方法,而run方法对于每一个对象又是相同的,这样就造成了不必要的内存浪费。如果可以将run方法共享出来就可以避免这种问题,函数的prototype(原型)属性可以帮我们做到,下面我们认识一下函数的prototype(原型)属性。
原型(prototype)
首先原型也是一个对象,该对象随着函数的创建而创建,其特点为,可以让所有通过该函数创建的对象实例共享它里面的属性和方法。访问过程如下图所示:在我们new一个实例时,该实例会有一个__proto__属性,该属性执行原型的constructor属性,这样就可以访问到原型里面的属性和方法了,每一个实例都是如此。
组合构造函数+原型模式
由此,利用原来的构造函数,再加上原型模式就可以解决上边的问题了。代码如下:function Box(name, age) { //不共享的使用构造函数 this.name = name; this.age = age; this. family = ['父亲', '母亲', '妹妹']; }; Box.prototype = { //共享的使用原型模式 constructor : Box, run : function () { return this.name + this.age + this.family; } };
有关代码中的constructor : Box,是为了让实例的constructor强制指向它的对象所属,否则创建的实例不是指向它的对象所属的,也就是box的constructor不指向Box,而是指向Object。
特点分析:这种方法将不需要共享的属性放在构造函数里初始化,将需要共享的方法放在原型里初始化。
缺点分析:其实这种方法算是一种比较好的方法了,但是还存在的问题在于,原型中共享的方法无论是否调用到都会初始化,如果该方法比较大的话,也会造成不必要的内存浪费,同时由于构造和原型在形式上是分离的,如果封装到一起看起来就更直观和方便。
动态原型:
针对上边的问题,利用下边的代码,动态的调用原型中的方法。function Box(name ,age) { //将所有信息封装到函数体内 this.name = name; this.age = age; if (typeof this.run != 'function') { //仅在第一次调用的初始化 Box.prototype.run = function () { return this.name + this.age + '运行中...'; }; } } var box = new Box('Lee', 100); alert(box.run());
继承
在JAVA的面向对象编程中,实现继承的方式有接口实现和继承两种方式,但是在JavaScript中是不支持接口实现的,在这里继承的实现是依靠原型链实现的。基本继承:
先看代码function Box() { //Box 构造 this.name = 'Lee'; } function Desk() { //Desk 构造 this.age = 100; } Desk.prototype = new Box(); //Desc 继承了Box,通过原型,形成链条 var desk = new Desk(); alert(desk.age); alert(desk.name); //得到被继承的属性
从代码中我们可以看出,在JavaScript中的继承实现的过程就是,将父对象的实例放到了子对象的原型中实现的。通过上边的知识我们知道,函数原型中的内容是被函数的实例所共享的,所以就实现了子类型访问父类型属性和方法的过程。
缺点分析:这种方式无法实现子类型向父类型传参。
原型链+借用构造函数
为了解决上边的问题,我们可以借助借用构造函数也称对象冒充的方法实现,代码如下:function Box(age) { this.name = ['Lee', 'Jack', 'Hello'] this.age = age; } Box.prototype.run = function () { return this.name + this.age; }; function Desk(age) { Box.call(this, age); //对象冒充 } Desk.prototype = new Box(); //原型链继承 var desk = new Desk(100); alert(desk.run());
特点分析:从上边的代码可以看出,通过Desk.prototype
= new Box(),将Box继承了下来,同时在newDesk(参数) 的过程中传入参数,调用了Box.call(参数) 方法,将参数传递给了Box的构造函数。
总结
上边的介绍也只是利用面向对象的思想指导JavaScript的运用,真正在实际开发中还需要多思考最适合运用的方法,这些也是自己初步的一个认识,也算是给各位初学者提供一个思路,希望在以后能写出自己的面向对象的代码,同时也祝福各位!相关文章推荐
- JavaScript的面向对象机理
- JavaScript的面向对象机理1)-类
- JavaScript 面向对象程序设计(上)——封装[转]
- prototype.js 让你更深入的了解javascript的面向对象特性(转)
- JavaScript面向对象特性实践一
- JavaScript 面向对象程序设计(下)--继承与多态
- JavaScript 面向对象程序设计(下)——继承与多态
- 基于ECMA 的JavaScript 的面向对象程序设计
- JavaScript 与面向对象实战.
- AJAX语言——对象面向的JavaScript
- JavaScript 面向对象程序设计(下)——继承与多态(转)
- JavaScript 面向对象程序设计(上)——封装(转)
- JavaScript 面向对象程序设计(上)——封装
- JavaScript 面向对象程序设计(下)——继承与多态
- JavaScript的面向对象机理2)-继承
- 面向对象的 Javascript 面向对象基础
- javascript面向对象支持
- Javascript的面向对象
- javascript 面向对象开发一
- [原创] 面向对象之JavaScript脚本也疯狂!--OxScript反射功能预览