生活随笔
收集整理的這篇文章主要介紹了
如何理解并学习javascript中的面向对象(OOP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文不適合javascript初學者看(javascript水平還停留在函數級別的朋友,看了會覺得很暈的)。如果你想讓你的javascript代碼變得更加優美,性能更加卓越。或者,你想像jQuery的作者一樣,寫出屬于自己優秀的類庫(哪怕是基于jquery的插件)。那么,你請務必要學習javascript面向對象,否則你無法更靈活的使用javascript這門語言。
什么事閉包?到底什么是原型?(知道閉包和原型的,就算得上是javascript的高手了。但真正能夠理解,并且靈活運用的人并不多)到底該如何學習javascript中的面向對象呢?在javascript這么語言正如日中天,相信不少人正在為此而困惑。
本文中,我講用代碼+詳細注釋的方式,一行行一步步講述javascript中的面向對象編程。當然有些只是我個人的理解,不足之處,敬請諒解!
?
1.下面部分的代碼,將是從目前十分流行的JSON數據格式以及javascript數組,來一步步像大家闡述javascript中的面向對象思想。
?
view plain
<!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>??????<title>JSON數據格式</title>??????<script?src="Scripts/jquery-1.4.1-vsdoc.js"?type="text/javascript"></script>???????<script?type="text/javascript">???????????function?jsonTest()?{???????????????//定義json數據格式?--?以文本的形式存在,轉換為javascript對象或者數組???????????//對象中可以包含數組,數組中也可以包含對象,可以存在相互嵌套的關系???????????????var?json1?=?"[1,2,{a:123,b:'str',c:[100,200]}]";//數組形式???????????????var?parsejson1?=?eval(json1);//將純文本的內容轉換為javascript原生支持的json???????????????var?json2?=?"{name:'dinglang',age:21,hobby:['武術','電影']}";//對象形式???????????????//var?parsejson2?=?eval(json2);?//這樣直接轉換會報錯????????????????//當被eval()轉換的純文本json數據為對象形式時,需要在前后加上"()"???????????????var?parsejson2?=?eval("("?+?json2?+?")");?//這樣轉換就可以了?????????????????????????????alert("");???????????}???????????????????//探索一下JSON這種數據格式的由來?????????????//1.首先是回顧一下javascript數組的相關知識???????????function?arrTest()?{??????????????//?1)數組的基本定義與賦值???????????????var?arrOne?=?new?Array();?//第一種創建方法???????????????var?arrTwo?=??new?Array(0,1,2);//第二種創建方式(創建的時候就給數組賦初始值)???????????????var?arrThree?=?[];?//第三種方式?--定義一個空數組???????????????var?arrFour?=?[1,?2,?3,?5];?//第四種方式--定義一個數組,并給數組賦初始值???????????????//創建多維數組???????????????var?arrFive?=?new?Array(1,?new?Array(2,?3),?4,?5);?//創建一個多維數組(嵌套的)???????????????var?arrSix?=?[1,?[2,?3],?4];//創建一個多維數組???????????????//?2)數組的基本操作(數組是javascript語言中一種很重要的數據結構)???????????????alert(arrSix[1]);??//通過數組下標,來獲取數組中對應的某個元素???????????????arrSix[0]?=?100;?//給數組中下標對應的元素賦值(如果該元素還未創建,就創建該元素并賦值)???????????????arrSix[99]?=?888;?//arrSix中會自動創建下標為99的元素,并給其賦值?--javascript中數組的長度是可以隨時改變的???????????????//?3)javascript當中數組常用的一些方法???????????????//concat方法的使用?--可以做數組的連接或者合并,原數組的內容不變,將返回一個新的數組對象???????????????var?arrFourarrFour1?=?arrFour.concat(101,?102,?103);//第一種連接方式???????????????var?arrFourarrFour2?=?arrFour.concat([104,?105]);//第二種連接方式???????????????var?arrFourarrFour3?=?arrFour.concat(arrFour1);?//將已經定義的數組進行連接???????????????//join方法--將數組中元素,按照指定的分隔符連接成字符串輸出,原數組的內容不變???????????????//slice方法--返回當前數組中的子數組,原數組中的內容不會改變???????????????//push/pop??在數組的尾端追加(push)或彈出(pop),將會修改原數組的內容???????????????arrFive.push(107);//在數組尾部追加一個元素???????????????arrFive.pop();?//彈出數組中最后一個元素???????????????//在數組的開頭追加(shift)和unshift(彈出)操作???????????????arrFive.reverse();?//反轉數組中的元素???????????????arrFive.sort();?//按照字母是順序,對數組中的元素進行升序排列???????????????arrFive.sort(function?(a,?b)?{???????????????????return?a?-?b;???????????????});?//按照數值大小,進行升序排列。如果返回的是負值,那么a就會出現在b的前面???????????????arrFive.sort(function?(a,?b)?{???????????????????return?b?-?a;???????????????});?//按照降序排列???????????????//splice??可以刪除數組中一部分元素,并把部分元素進行返回。也可以在指定位置添加元素???????????????var?arrSplice1?=?arrSix.splice(3,?2);?//從下標為3的元素開始刪除,刪除2個元素???????????????var?arrSplice2?=?arrSix.splice(4);?//從下標為4的元素開始刪除,一直刪除到數組的末尾???????????????arrSix.splice(1,?0,?401,?402);?//在下標為1的元素前面,插入401,402這兩個元素???????????????arrSix.splice(1,?0[188,?189]);//在下標為1的元素前面,插入[188,199]???????????}??????????????????????//2.javascript中的對象的定義、使用???????????var?obj1?=?new?Object();?//定義一個對象???????????var?obj2?=?{};??//使用"{}"也可以定義一個對象???????????//給對象增加屬性???????????obj1.num?=?1;???????????obj1.str?=?"string";???????????obj1.sayHello?=?function?()?{???????????????alert("Hello");???????????}???????????obj2.srcObj?=?obj1;?//將obj1對象作為obj2對象的屬性?????????????//屬性的訪問?--第一種訪問方式???????????obj1.num;?//也可以這么訪問??obj2.srcObj.num;???????????obj1.str;???????????//obj2.srcObj.str;???????????obj1.sayHello();???//obj2.srcObj.sayHello();?????????????//屬性的訪問?--第二種方式???????????obj1["num"];????????//obj2["srcObj"]["num"];???????????obj1["str"];????????//obj2["srcObj"]["str"];???????????obj1["sayHello"]();?//obj2["srcObj"]["sayHello"]();?????????????//通過對象直接量的方式,定義和調用對象、屬性???????????var?obj3?=?{???????????????num:?1,???????????????str:?"string",???????????????sayHello:?function?()?{???????????????????alert('Hello');???????????????}???????????}???????????//訪問方式同上,例如???????????obj3.num;?//obj3["num"];?????????????//看清楚了嗎?這就是javascript中JSON數據格式的原型?????????????????//下面來深入講解javascript語言的面向對象特性???????????//javascript中定義類,需要用function來模擬????//?????????function?Teacher(){??//????????????????????//?????????}????????????//建議使用下面這種方法來創建一個類,以便將類和函數區分開來(建議定義類時首字母大寫)???????????var?Teacher?=?function?()?{?????????????}???????????//定義一個book類,這里的function還承擔了構造函數的工作???????????//在使用new操作符創建Book對象時,這個funtion里面的代碼將會被執行一次???????????//this關鍵字代表的是當前對象???????????function?Book(name)?{???????????//定義公有的屬性???????????????this.name?=?name;???????????????//定義公有的函數???????????????this.getName?=?function?()?{???????????????????return?this.name;???????????????}???????????????this.setName?=?function?(nname)?{???????????????????this.name?=?nname;???????????????}???????????}???????????function?ooTest()?{???????????????var?tech?=?new?Teacher();???????????????alert(tech?instanceof?Teacher);?//?instanceof函數,表示是否屬于某對象類型???????????????var?book1?=?new?Book("C#");//這里的new操作相當于先創建了一個簡單對象,調用了類的構造函數???????????????var?book2?=?new?Book("JAVA");???????????????alert(book1.name);//彈出C#???????????????alert(book2.name);//彈出JAVA???????????????book1.setName(".NET");???????????????alert(book1.name);//彈出.NET???????????????alert(book2.name);?//彈出JAVA?????????????????//function上面都有一個原型對象?--prototype???????????????var?proto?=?Book.prototype;???????????????proto.str?=?"string";???????????????proto.hello?=?function?()?{???????????????????alert("Hello");???????????????}???????????????//給原型定義了屬性和方法后,擁有這個原型對象的function模擬出來的類,也具有該屬性和方法???????????????alert(book1.str);?//彈出string???????????????book1.hello();?//彈出hello?????????????}??????????????????</script>??</head>??<body>??<input??type="button"?value="測試json"?onclick="jsonTest()"/>??</body>??</html>?? ?
?
2.下面部分代碼,是從另外一個角度講解javascript中的面向對象編程。是借鑒EasyJF開源團隊的講解,我個人做了一些補充和說明。
?
view plain
<!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>??????<title>javascript面向對象編程</title>??????<script?src="Scripts/jquery-1.4.1-vsdoc.js"?type="text/javascript"></script>??????<script?type="text/javascript">??????????$(function?()?{????????????????//????????????function?animal(name)?{??????????????//????????????????this.name?=?name;??????????????//????????????????this.age?=?0;??????????????//????????????}??????????????//????????????var?a1?=?animal;??????????????//????????????alert(a1);//彈出整個函數體??????????????//????????????var?a2?=?animal("dinglang");??????????????//????????????alert(a2);?//彈出undefined??????????????//????????????var?a3?=?new?animal();??????????????//????????????alert(a3);//彈出object??????????????//????????????var?a4?=?new?animal;??????????????//????????????alert(a4);//彈出object??????????????????//求值??????????????//alert(sum(1,?3));?//要求彈出結果為4??????????????//?alert(sum(1,?3,?5,?4,?7));?//要求彈出結果為20??????????????//根據java或者C#的編程經驗,首先想到的是函數重載。??????????????//????????????function?sum(a,?b)?{??????????????//????????????????return?a?+?b;??????????????//????????????}??????????????//????????????function?sum(a,?b,?c,?d,?e)?{??????????????//????????????????return?a?+?b?+?c?+?d?+?e;??????????????//????????????}??????????????//不幸的是,javascript并不支持函數重載。如果照上面那么寫,只有下面的那個函數才會生效????????????????//javascript支持可變參數的函數??????????????function?sum()?{????????????????????var?n?=?0;??????????????????for?(var?i?=?0;?i?<?arguments.length;?i++)?{??????????????????????n?+=?arguments[i];??????????????????}??????????????????return?n;??????????????}????????????????//javascript高級知識?--?閉包??????????????//函數里面嵌套函數,且在外部被引用了,所以這個對象i不會被垃圾回收機制清除,所以i遞增??????????????function?f1()?{??????????????????var?i?=?0;??????????????????var?f2?=?function?()?{??????????????????????i++;??????????????????????alert(i);??????????????????}??????????????????return?f2;?//f2對象指的是整個函數體??????????????}??????????????var?f3?=?f1();?//?"f1()"就是指該函數的執行結果或者返回值?--f2??????????????//???????????f3();//1??????????????//????????????f3();//2??????????????//????????????f3();//3??????????????????//作用域與this關鍵字??????????????//????????????var?obj?=?new?Object();??????????????//????????????obj.v?=?"v?is?a?object";??????????????//????????????//相當于這么寫??????????????//???????????var?obj2?=?{?v:?"v?is?a?object"?};??????????????//作用域Scope??????????????var?b1?=?{?v:?"this?is?b1"?};??????????????var?b2?=?{?v:?"this?is?b2"?};??????????????function?b(x,?y)?{??????????????????//??alert(this.v?+?","?+?x?+?","?+?y);??????????????}??????????????b("ding",?"lang");?//undefined,"ding","lang"???????????????//調用b函數時,b函數中的this關鍵字指的是window對象.而Window對象中沒有v對象,所以undefined??????????????//window.b("ding",?"lang");?//undefined,"ding","lang"???--與?b("ding",?"lang");意義相同??????????????//b.call();//就等于b();??????????????//call函數的第一個參數表示的是函數的上下文?--表示b函數中的this?所以this關鍵字=b1??????????????//?b.call(b1,?"ding",?"lang");?//this?is?b1,ding,lang??????????????//注意apply函數的用法:第一個參數表示的也是函數中的上下文。不過后面的參數要以數組的形式傳遞??????????????//?b.apply(b2,?["ding",?"lang"]);?//?//this?is?b1,ding,lang????????????????//關于作用域,再補充一點??????????????var?b3?=?{?v:?"this?is?b3",??????????????????sayHello:?function?()?{??????????????????????alert(this.v);??????????????????}??????????????}??????????????//?b3.sayHello();?//this?is?b3??????????????//b3.sayHello.call(b1);?//會調用b1對象中的sayHello函數??--?this?is?b1??????????????????//?for?...?in??????????????//????????????var?arr?=?new?Array();?//new?一個js數組,與c#、java等編程語言不同,可以不指定長度??????????????//????????????arr[0]?=?1;?//賦值??????????????//????????????arr[1]?=?2;??????????????//????????????arr[2]?=?3;??????????????//javascript支持直接定義賦值??????????????var?arr?=?new?Array(1,?2,?3);??????????????for?(var?i?=?0;?i?<?arr.length;?i++)?{??????????????????//?alert(arr[i]);?//彈出?1,2?,3???????????????}??????????????//注意:javascript中的for...in?,看起來與C#或者java中的foreach類似,但是不同??????????????for?(var?key?in?arr)?{??????????????????//?alert(key);//?彈出0,1,2???key指的是鍵,而不是值。在C#的foreach中,“in”前的變量指的是值??????????????????//alert(arr[key]);//可以使用這種方式取值?--key指的是鍵,也就是某個對象中包含的所有的對象,而不是值??????????????}??????????????//假如我沒有firebug,想使用IE實現類似與firebug控制臺中console.dir的功能,可以這樣??????????????for?(var?key?in?window)?{??????????????????//?這樣就能將window對象中,包含的全部對象迭代顯示出來。也就實現了firebug中console.dir的功能??????????????????//document.getElementById("key").innerHTML?+=?(key?+?":"?+?window[key]?+?"</br>");??????????????}????????????????//對象的刪除(釋放內存--?在extjs組件中常用)??????????????//????????????delete?b3.v;?//刪除b3對象中的v成員??????????????//????????????alert(b3.v);?//?undefined?--因為v這個成員已經被刪除了????????????????//類的修改,擴展(重點,難點)??????????????//1.假如我要實現一個簡單的加法計算??????????????//???????var?numOne?=?5;//如果直接這么定義,那么下面的numOne.add(8);執行會報錯??????????????//如果我這么寫,下面調用就不會報錯了(因為此時的numOne,是個類.相當于java或C#語言中原始的基本數據類型、包裝類型)??????????????var?numOne?=?new?Number(5);??????????????numOne.add?=?function?(numTwo)?{??????????????????return?this?+?numTwo;??????????????}??????????????//alert(numOne.add);?//undefined??????????????//?alert(numOne.add(8));//這樣寫看起來沒錯,但是會報錯--numOne.add?is?not?a?function??????????????var?numThree?=?new?Number(100);??????????????//如果我現在想要給numThree對象中也加上add這么一個函數??????????????//直接使用prototype這個特殊的屬性來實現,給所有的Number類型實例都加入add函數??????????????Number.prototype.add?=?function?(numTwo)?{??????????????????return?this?+?numTwo;??????????????}????????????????alert(numThree.add(200).add(300));?//彈出600???100+200+300=600????????????????//說明所有的Number類型確實都具有了add這么一個函數???超級延時綁定--類的擴展????????????????//小例子?--擴展String類,給所有的String類加上sayILoveYou??????????????//????????????String.prototype.sayILoveYou?=?function?()?{??????????????//????????????????alert(this.toString()?+?",?I?Love?You");??????????????//????????????}??????????????//????????????var?strOne?=?"dinglang";??????????????//????????????strOne.sayILoveYou();????????????????//javascript中的類的用法??????????????//使用構造函數的方式,定義簡單的Person類(javascript函數也是一個類)??????????????function?Person(name)?{????????????????????this.name?=?name;??????????????????this.age?=?20;??????????????????var?year?=?2010;?//定義一個私有的成員sex??????????????????//????????????????this.sayHello?=?function?()?{??????????????????//????????????????????alert(this.name?+?":今年"?+?this.age?+?"歲,HelloWold");??????????????????//可以直接在這里面定義sayHello成員函數(特權方法),但是每次實例化該類的時候都會重新去定義,所有還是選擇用prototype屬性的方式??????????????????//如果在sayHello函數中要使用year這個私有對象,就可以直接在此定義這個特權方法。這就是典型的“閉包”。??????????????}??????????????//如果使用了new關鍵字,說明Person就是一個類。否則的話,只是一個普通的函數??????????????var?p1?=?new?Person("丁浪");?//?new?一個Person類的實例???????????????var?p2?=?new?Person("蔡世友");?//注意:別按照java或者C#的習慣,寫成了Person?p?=new?Person("XXX");???????????????//給Person這個自定義的類,添加一個sayHello函數??????????????Person.prototype.sayHello?=?function?()?{??????????????????alert(this.name?+?":今年"?+?this.age?+?"歲,HelloWold");??????????????}??????????????p1.sayHello();??????????????p2.sayHello();????????????????//實現javascript中的繼承????????????????function?classA(name)?{??????????????????this.name?=?name;??????????????????this.showName?=?function?()?{??????????????????????alert(this.name);??????????????????}??????????????}??????????????function?classB(name)?{??????????????????//1)使用newMethod的方式實現繼承??????????????????//????????????????this.newMethod?=?classA;??????????????????//????????????????this.newMethod(name);??????????????????//????????????????delete?this.newMethod;?//釋放對象??????????????????//2)調用claasA這個函數,并把他的上下文(作用域)指向this(也就是classB類的實例)??????????????????//這樣也能實現繼承效果(使用call或者apply)??????????????????classA.call(this,?name);??????????????????//classA.apply(this,[name]);??????????????}??????????????objA?=?new?classA("操作系統");??????????????objB?=?new?classB("組成原理");??????????????objA.showName();?//彈出“操作系統”??????????????objB.showName();?//彈出“組成原理”????????????})??????</script>??</head>??<body>??<div?id="key">?</div>??</body>??</html>?? ?本文出自blog.csdn.net/dinglang_2009,轉載請注明出處。未經本人允許,任何人不得借此牟利。
轉載于:https://www.cnblogs.com/dinglang/archive/2011/10/29/2228956.html
總結
以上是生活随笔為你收集整理的如何理解并学习javascript中的面向对象(OOP)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。