JavaScript 面向對象(三)——高級篇 JSON 數據格式

JavaScript  面向對象(一)——基礎篇javascript

JavaScript  面向對象(二)——案例篇html

1、json方式的面向對象java

首先要知道,js中出現的東西都可以放到json中。關於json數據格式這裏推薦一篇博客:JSON 數據格式json

先看下json建立的簡單對象:相比基礎篇中的構造函數、原型等的建立方式,json方式簡單方便;可是缺點很明顯,若是想建立多個對象,那麼會產生大量重複代碼,不可取。數組

JSON方式適用於只建立一個對象的狀況,代碼簡介又優雅。函數

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <title></title>
 6         <script>
 7             var person = {
 8                 name: "jiangzhou",
 9                 age: 22,
10                 showName: function(){
11                     alert(this); //[Object Object]
12                     alert("姓名:"+this.name);
13                 },
14                 showAge: function(){
15                     alert("年齡:"+this.age);
16                 }
17             };
18             person.showName();
19             person.showAge();
20             
21         </script>
22     </head>
23 </html>

JSON在JS面向對象的應用中,主要的一個做用就是命名空間:若是有大量經常使用的js函數,利用json,咱們能夠將同一類函數放在一個「類」裏,相似於java那樣,這樣咱們就能很好的管理和查找使用這些js函數,看下面的例子就很好理解了。post

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <title></title>
 6         <script>
 7             //仿java.lang包
 8             var lang = {};
 9             
10             /**
11              * 仿java.lang.Math類
12              */
13             lang.Math = {
14                 /**
15                  * 求絕對值
16                  * @param {Object} a
17                  */
18                 abs: function(a){
19                     return a > 0 ? a : -a;
20                 },
21                 /**
22                  * 求最大值
23                  * @param {Object} a
24                  * @param {Object} b
25                  */
26                 max: function(a, b){
27                     return a > 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: function(str){
44                     return str.length;
45                 },
46                 /**
47                  * 將字符串轉爲小寫
48                  * @param {Object} str
49                  */
50                 toLowerCase: function(str){
51                     return str.toLowerCase();
52                 },
53                 /**
54                  * 將字符串轉爲大寫
55                  * @param {Object} str
56                  */
57                 toUpperCase: function(str){
58                     return str.toUpperCase();
59                 }
60             }
61             
62             //調用
63             alert(lang.Math.abs(-19)); //19
64             alert(lang.Math.PI);
65             alert(lang.String.toUpperCase("abcdefg")); //ABCDEFG
66             
67         </script>
68     </head>
69 </html>

2、面向對象的繼承this

先舉個簡單的例子來講一下JS中的繼承,Student <extends> Person;url

在js中,經過call來調用父類的構造方法繼承父類的屬性(第33行),經過原型來繼承父類的方法(第39行)。注意:先調用父類構造函數,再添加本身的屬性;先繼承父類的方法,再添加本身的方法。spa

這裏解釋下爲何調用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行),爲何呢?先思考下,下面解釋。

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             
 7             /**
 8              * Person 父類 人
 9              * @param {Object} name 姓名
10              * @param {Object} sex 性別
11              */
12             function Person(name, sex){
13                 this.name = name;
14                 this.sex = sex;
15             }
16             Person.prototype.showName = function(){
17                 alert("姓名:"+this.name); 
18             }
19             Person.prototype.showSex = function(){
20                 alert("性別:"+this.sex); 
21             }
22             
23         /*-----------------------------------------------------*/
24             
25             /**
26              * Student   學生 繼承 人
27              * @param {Object} name
28              * @param {Object} sex
29              * @param {Object} major 學生特有屬性:專業
30              */
31             function Student(name, sex, major){
32                 //調用父類的構造函數
33                 Person.call(this, name, sex);
34                 
35                 //添加本身的屬性
36                 this.major = major;
37             }
38             //繼承父類原型中的方法
39             Student.prototype = Person.prototype;
40             //添加本身特有的方法
41             Student.prototype.showMajor = function(){
42                 alert("專業:"+this.major);
43             }
44             
45             var student = new Student("bojiangzhou", "男", "信息管理");
46             student.showName();
47             student.showSex();
48             student.showMajor();
49             
50             alert(Person.prototype.showMajor);
51         </script>
52     </head>
53 </html>

第50行彈出的信息:

爲了解釋爲何經過Student.prototype = Person.prototype來繼承父類的方法會影響父類,下面舉一個數組的例子,一看就知道怎麼回事了。

爲何arr1和arr2彈出來的同樣呢?第1五、16行顯示arr1和arr2是一個對象。對象!應該很清楚了吧,arr1和arr2都是指向這個數組對象的一個引用,因此改變arr2時,arr1也變了。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5     </head>
 6     <script>
 7         var arr1 = [1,2,3,4,5];
 8         var arr2 = arr1;
 9         
10         arr2.push(6);
11         
12         alert(arr1); //彈出1,2,3,4,5,6
13         alert(arr2); //彈出1,2,3,4,5,6
14         
15         alert(typeof arr1); //object
16         alert(typeof arr2); //object
17     </script>
18 </html>

其實咱們主要是想得到arr1數組的一個副本,怎麼作才能不改變arr1呢,看下面:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5     </head>
 6     <script>
 7         var arr1 = [1,2,3,4,5];
 8         var arr2 = [];
 9         
10         //複製arr1的數據便可
11         for(var i=0;i<arr1.length;i++){
12             arr2[i]=arr1[i];
13         }
14         
15         arr2.push(6);
16         
17         alert(arr1); //彈出1,2,3,4,5
18         alert(arr2); //彈出1,2,3,4,5,6
19         
20     </script>
21 </html>

一樣的,咱們也能夠經過這種方式爲繼承的子類添加父類原型中的方法,而又不影響父類(38-41行):

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             
 7             /**
 8              * Person 父類 人
 9              * @param {Object} name 姓名
10              * @param {Object} sex 性別
11              */
12             function Person(name, sex){
13                 this.name = name;
14                 this.sex = sex;
15             }
16             Person.prototype.showName = function(){
17                 alert("姓名:"+this.name); 
18             }
19             Person.prototype.showSex = function(){
20                 alert("性別:"+this.sex); 
21             }
22             
23         /*-----------------------------------------------------*/
24             
25             /**
26              * Student   學生 繼承 人
27              * @param {Object} name
28              * @param {Object} sex
29              * @param {Object} major 學生特有屬性:專業
30              */
31             function Student(name, sex, major){
32                 //調用父類的構造函數
33                 Person.call(this, name, sex);
34                 
35                 //添加本身的屬性
36                 this.major = major;
37             }
38             //繼承父類原型中的方法
39             for(var p in Person.prototype){
40                 Student.prototype[p] = Person.prototype[p];
41             }
42             
43             //添加本身特有的方法
44             Student.prototype.showMajor = function(){
45                 alert("專業:"+this.major);
46             }
47             
48             var student = new Student("bojiangzhou", "男", "信息管理");
49             student.showName();
50             student.showSex();
51             student.showMajor();
52             
53             alert(Person.prototype.showMajor);
54         </script>
55     </head>
56 </html>

第53行彈出信息:Person中沒有showMajor方法了。

最後,以案例篇中最後給出的拖拽例子來應用下繼承,那個拖拽有一個問題,就是沒有控制拖拽出邊界的問題。

先貼出以前的拖拽版本:

drag.js:

 1 /**
 2  * 拖拽
 3  * @param {Object} id div的id
 4  */
 5 function Drag(id){
 6     this.oBox = document.getElementById(id);
 7     this.disX = 0;
 8     this.disY = 0;
 9     
10     var _this = this;
11     
12     this.oBox.onmousedown = function(){
13         _this.fnDown();
14     }
15 }
16 //鼠標按下
17 Drag.prototype.fnDown = function(ev){
18     var oEvent = ev || event;
19     
20     this.disX = oEvent.clientX - this.oBox.offsetLeft;
21     this.disY = oEvent.clientY - this.oBox.offsetTop;
22     
23     var _this = this;
24     
25     document.onmousemove = function(){
26         _this.fnMove();
27     };
28     document.onmouseup = function(){
29         _this.fnUp();
30     };
31 }
32 //鼠標移動
33 Drag.prototype.fnMove = function(ev){
34     var oEvent= ev || event;
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 = function(){
41     document.onmousemove = null;
42     document.onmouseup = null;
43 }

drag.html:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <style>
 6             div {
 7                 position: absolute;
 8             }
 9         </style>
10         <title>拖拽</title>
11         <script type="text/javascript" src="../js/drag.js" ></script>
12         <script>
13             window.onload = function(){
14                 var drag1 = new Drag("box1");
15                 
16                 var drag1 = new Drag("box2");
17             };
18         </script>
19     </head>
20 
21 <body>
22     <div id="box1" style="background: red;width: 200px;height: 200px;"></div>
23     
24     <div id="box2" style="background: blue;width: 100px;height: 300px;"></div>
25 </body>
26 </html>

效果:能夠看到紅色和藍色的都出邊界了,但咱們又不想去修改代碼,那咱們怎麼作?學過java的應該都知道能夠寫一個子類來作一些更加具體的操做,又保留了父類的功能,就是繼承。

DragLimit.js:DragLimit繼承自Drag,控制了不能出邊界

 1 /**
 2  * 限制邊界的拖拽,繼承自Drag
 3  * @param {Object} id
 4  */
 5 function DragLimit(id){
 6     Drag.call(this, id);
 7 }
 8 //繼承方法
 9 for(var p in Drag.prototype){
10     DragLimit.prototype[p] = Drag.prototype[p];
11 }
12 /**
13  * 覆寫父類的鼠標移動方法,控制不能移出邊界
14  */
15 DragLimit.prototype.fnMove = function(ev){
16     var oEvent= ev || event;
17     
18     var left = oEvent.clientX - this.disX;
19     var top = oEvent.clientY - this.disY;
20     
21     //控制邊界
22     if(left < 0){
23         left = 0;
24     } else if(left > document.documentElement.clientWidth-this.oBox.offsetWidth){
25         left = document.documentElement.clientWidth-this.oBox.offsetWidth;
26     }
27     if(top <= 0){
28         top = 0;
29     } else if(top > document.documentElement.clientHeight-this.oBox.offsetHeight){
30         top = document.documentElement.clientHeight-this.oBox.offsetHeight;
31     }
32     
33     this.oBox.style.left = left + 'px';
34     this.oBox.style.top = top + 'px';
35 }

dragLimit.html

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <style>
 6             body {
 7                 padding: 0;
 8                 margin: 0;
 9             }
10             div {
11                 position: absolute;
12             }
13         </style>
14         <title>拖拽</title>
15         <script type="text/javascript" src="../js/drag.js" ></script>
16         <script type="text/javascript" src="../js/dragLimit.js" ></script>
17         <script>
18             window.onload = function(){
19                 var drag1 = new Drag("box1");
20                 
21                 var drag1 = new DragLimit("box2");
22             };
23         </script>
24     </head>
25 
26 <body>
27     <div id="box1" style="background: red;width: 200px;height: 200px;"></div>
28     
29     <div id="box2" style="background: blue;width: 100px;height: 300px;"></div>
30 </body>
31 </html>

效果:藍色是不能移出邊界的。

3、JS中的對象

js中的對象分爲本地對象、內置對象、宿主對象,這裏給出W3School文檔供參考:ECMAScript 對象類型

相關文章
相關標籤/搜索