一、json方式的面向对象
首先要知道,js中出现的东西都能够放到json中。关于json数据格式这里推荐一篇博客:JSON 数据格式
先看下json创建的简单对象:相比基础篇中的构造函数、原型等的创建方式,json方式简单方便;但是缺点很明显,如果想创建多个对象,那么会产生大量重复代码,不可取。
JSON方式适用于只创建一个对象的情况,代码简介又优雅。
1 <!DOCTYPE html>
2 <html 3 head 4 Meta charset="UTF-8" 5 title></ 6 script 7 var person = {
8 name: "jiangzhou, 9 age: 2210 showName: function(){
11 alert(this); //[Object Object]
12 姓名:+.name);
13 },1)">14 showAge: 15 年龄:.age);
16 }
17 };
18 person.showName();
19 person.showAge();
20
21 </22 23 >
JSON在JS面向对象的应用中,主要的一个作用就是命名空间:如果有大量常用的js函数,利用json,我们可以将同一类函数放在一个“类”里,类似于java那样,这样我们就能很好的管理和查找使用这些js函数,看下面的例子就很好理解了。
仿java.lang包
8 lang {};
9
10 /**
* 仿java.lang.Math类
12 */
lang.Math 14 * 求绝对值
* @param {Object} a
17 abs: (a){
19 return a > 0 ? a : -a;
20 21 22 * 求最大值
23 24 * @param {Object} b
25 26 max: (a,b){
27 > b a : b;
28 29 30 * PI
31 32 PI: 3.1415926
33 }
34
35 36 * 仿java.lang.String类
37 38 lang.String 39 40 * 求字符串长度
41 * @param {Object} str
42 43 length: (str){
44 str.length;
45 46 47 * 将字符串转为小写
48 49 50 toLowerCase: 51 str.toLowerCase();
52 53 54 * 将字符串转为大写
55 56 57 toUpperCase: 58 str.toUpperCase();
59 60 61
62 调用
63 alert(lang.Math.abs(19)); 19
64 alert(lang.Math.PI);
65 alert(lang.String.toUpperCase(abcdefgABCDEFG
66
67 68 69 >
二、面向对象的继承
先举个简单的例子来说一下JS中的继承,Student <extends> Person;
在js中,通过call来调用父类的构造方法继承父类的属性(第33行),通过原型来继承父类的方法(第39行)。注意:先调用父类构造函数,再添加自己的属性;先继承父类的方法,再添加自己的方法。
这里解释下为什么调用Person.call(this,name,sex)就相当于是在调用父类的构造方法:先问一下这个call中的this是谁?这里指向对象student吧。
所以,在子构造函数中调用Person.call()时,那么构造函数Person里的两行代码this.name=name,this.sex=sex中this就是代表student了,所以这两行代码相当于是在为student添加name和sex属性。
但是,下面的通过原型来继承父类的方法,即Student.prototype = Person.prototype,是有问题的,这种方式将影响父类(继承是不能影响父类的),此时Person的原型中有了个showMajor方法(第50行),为什么呢?先思考下,下面解释。
="UTF-8" />
4 6
* Person 父类 人
* @param {Object} name 姓名
* @param {Object} sex 性别
11 12 Person(name,sex){
13 .name name;
.sex sex;
Person.prototype.showName = alert(.name);
Person.prototype.showSex 性别:.sex);
21 22
23 -----------------------------------------------------24
25 * Student 学生 继承 人
27 * @param {Object} name
* @param {Object} sex
29 * @param {Object} major 学生特有属性:专业
30 31 Student(name,sex,major){
32 调用父类的构造函数
Person.call(34
35 添加自己的属性
36 .major major;
37 38 继承父类原型中的方法
39 Student.prototype Person.prototype;
40 添加自己特有的方法
Student.prototype.showMajor 42 专业:.major);
44
45 student new Student(bojiangzhou男信息管理);
46 student.showName();
student.showSex();
student.showMajor();
49
alert(Person.prototype.showMajor);
51 52 53 >
第50行弹出的信息:
为了解释为什么通过Student.prototype = Person.prototype来继承父类的方法会影响父类,下面举一个数组的例子,一看就知道怎么回事了。
为什么arr1和arr2弹出来的一样呢?第15、16行显示arr1和arr2是一个对象。对象!应该很清楚了吧,arr1和arr2都是指向这个数组对象的一个引用,所以改变arr2时,arr1也变了。
5 6 7 arr1 [12345];
8 arr2 arr1;
9
arr2.push(611
alert(arr1); 弹出1,2,3,4,5,6
alert(arr2); 14
alert(typeof arr1); object
arr2); 17 18 >
其实我们主要是想获得arr1数组的一个副本,怎么做才能不改变arr1呢,看下面:
[];
10 复制arr1的数据即可
11 for( i0;i<arr1.length;i++){
arr2[i]arr1[i];
}
16
19
20 21 >
同样的,我们也可以通过这种方式为继承的子类添加父类原型中的方法,而又不影响父类(38-41行):
39 p in Person.prototype){
Student.prototype[p] Person.prototype[p];
42
43 44 47
48 49 51 52
53 54 55 56 >
第53行弹出信息:Person中没有showMajor方法了。
最后,以案例篇中最后给出的拖拽例子来应用下继承,那个拖拽有一个问题,就是没有控制拖拽出边界的问题。
先贴出之前的拖拽版本:
drag.js:
/* * 拖拽
3 * @param {Object} id div的id
4 5 function Drag(id){
this.oBox = document.getElementById(id);
7 this.disX = 0;
8 this.disY = 0 9
10 var _this = this11
12 this.oBox.onmousedown = 13 _this.fnDown();
14 }
15 }
16 //鼠标按下
17 Drag.prototype.fnDown = (ev){
18 var oEvent = ev || event;
19
this.disX = oEvent.clientX - .oBox.offsetLeft;
21 this.disY = oEvent.clientY - .oBox.offsetTop;
22
23 24
25 document.onmousemove = 26 _this.fnMove();
27 };
28 document.onmouseup = 29 _this.fnUp();
30 31 32 鼠标移动
33 Drag.prototype.fnMove = 34 var oEvent= ev ||35
36 this.oBox.style.left = oEvent.clientX - this.disX + 'px'37 this.oBox.style.top = oEvent.clientY - this.disY + 'px'38 39 鼠标抬起
40 Drag.prototype.fnUp = 41 document.onmousemove = null42 document.onmouseup = 43 }
drag.html:
style 6 div {
7 position: absolute;
}
9 10 >拖拽11 script type="text/javascript" src="../js/drag.js" 12 window.onload drag1 Drag(Box115
16 Box218 19 20
bodydiv id="Box1" style="background: red;width: 200px;height: 200px;"div23
24 ="Box2"="background: blue;width: 100px;height: 300px;"25 >
效果:可以看到红色和蓝色的都出边界了,但我们又不想去修改代码,那我们怎么做?学过java的应该都知道可以写一个子类来做一些更加具体的操作,又保留了父类的功能,就是继承。
DragLimit.js:DragLimit继承自Drag,控制了不能出边界
* 限制边界的拖拽,继承自Drag
* @param {Object} id
DragLimit(id){
6 Drag.call( 7 8 继承方法
9 for(var p in Drag.prototype){
10 DragLimit.prototype[p] = Drag.prototype[p];
11 12 * 覆写父类的鼠标移动方法,控制不能移出边界
14 15 DragLimit.prototype.fnMove = 16 17
var left = oEvent.clientX - .disX;
var top = oEvent.clientY - .disY;
20
控制边界
if(left < 023 left = 024 } else if(left > document.documentElement.clientWidth-.oBox.offsetWidth){
25 left = document.documentElement.clientWidth-.oBox.offsetWidth;
27 if(top <= 028 top = 029 } if(top > document.documentElement.clientHeight-.oBox.offsetHeight){
30 top = document.documentElement.clientHeight-.oBox.offsetHeight;
32
33 this.oBox.style.left = left + 'px'this.oBox.style.top = top + 'px'35 }
dragLimit.html
body padding 0 margin 9 13 14 15 16 ="../js/dragLimit.js" 17 19 20
DragLimit(23 25
28
29 >
效果:蓝色是不能移出边界的。
三、JS中的对象
js中的对象分为本地对象、内置对象、宿主对象,这里给出W3School文档供参考:ECMAScript 对象类型