成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

沒那么簡(jiǎn)單 那些應(yīng)該吃透的JavaScript概念

開發(fā) 前端
文章的目的是讓更多的程序員深入理解javascript的一些概念,其實(shí)關(guān)于這些,我們?cè)诳梢栽诰W(wǎng)上看到很多類似的內(nèi)容,所以現(xiàn)在該是向深入理解的方向靠攏的時(shí)候了。

文章的目的是讓更多的程序員深入理解JavaScript的一些概念,其實(shí)關(guān)于這些,我們?cè)诳梢栽诰W(wǎng)上看到很多類似的內(nèi)容,所以現(xiàn)在該是向深入理解的方向靠攏的時(shí)候了。

51CTO推薦閱讀:揭開JavaScript閉包的真實(shí)面目

一,function

從一開始接觸到j(luò)s就感覺好靈活,每個(gè)人的寫法都不一樣,比如一個(gè)function就有N種寫法。如:functionshowMsg(){},varshowMsg=function(){},showMsg=function(){}。似乎沒有什么區(qū)別,都是一樣的嘛,真的是一樣的嗎,大家看看下面的例子:

  1. //函數(shù)定義:命名函數(shù)(聲明式),匿名函數(shù)(引用式)  
  2. //聲明式,定義代碼先于函數(shù)執(zhí)行代碼被解析  
  3. functiont1(){  
  4. dwn("t1");  
  5. }  
  6. t1();  
  7. functiont1(){  
  8. dwn("newt1");  
  9. }  
  10. t1();  
  11. //引用式,在函數(shù)運(yùn)行中進(jìn)行動(dòng)態(tài)解析  
  12. vart1=function(){  
  13. dwn("newnewt1");  
  14. }  
  15. t1();  
  16. vart1=function(){  
  17. dwn("newnewnewt1");  
  18. }  
  19. t1();  
  20. //以上輸出:newt1,newt1,newnewt1,newnewnewt1 

可能想著應(yīng)該是輸出t1,newt1,newnewt1,newnewnewt1,結(jié)果卻并不是這樣,應(yīng)該理解這句話:聲明式,定義代碼先于函數(shù)執(zhí)行代碼被解析。如果深入一步,應(yīng)該說是scope鏈問題,實(shí)際上前面兩個(gè)方法等價(jià)于window.t1,可以理解為t1是window的一個(gè)公有屬性,被賦了兩次值,以最后一次賦值為最終值。而后面兩個(gè)方法,可以理解為是t1是個(gè)變量,第四個(gè)方法的var去掉之后的結(jié)果仍然不會(huì)改變。

然而,當(dāng)?shù)谒膫€(gè)方法改成functiont1(){}這樣的聲明式時(shí),結(jié)果變成了newnewnewt1,newnewnewt1,newnewt1,newnewt1。前面兩個(gè)按照我的理解可以很好的理解為什么是這個(gè)答案,第三個(gè)也可以理解,但是最后一個(gè)輸出讓我比較糾結(jié),希望有高手出現(xiàn)解答一下。另外匿名函數(shù)還有(function(){...})()這樣的寫法,最后一個(gè)括號(hào)用于參數(shù)輸入還有vart1=newfunction(){..}這樣的聲明,實(shí)際上t1已經(jīng)是一個(gè)對(duì)象了。

  1. vart2=newfunction()  
  2. {  
  3. vartemp=100;//私有成員  
  4. this.temp=200;//公有成員,這兩個(gè)概念會(huì)在第三點(diǎn)以后展開說明  
  5. returntemp+this.temp;  
  6. }  
  7.  
  8. alert(typeof(t2));//object  
  9. alert(t2.constructor());//300  
  10. 除此之外,還有使用系統(tǒng)內(nèi)置函數(shù)對(duì)象來構(gòu)建一個(gè)函數(shù),例:  
  11. vart3=newFunction('vartemp=100;this.temp=200;returntemp+this.temp;');//這個(gè)位置加不加new結(jié)果都一樣,WHY  
  12. alert(typeof(t3));//function  
  13. alert(t3());//300 

二,創(chuàng)建對(duì)象

首先我們理解一下面向?qū)ο缶幊蹋∣bject-OrientedProgramming,OOP),使用OOP技術(shù),常常要使用許多代碼模塊,每個(gè)模塊都提供特定的功能,每個(gè)模塊都是孤立的,甚至與其它模塊完全獨(dú)立。這種模塊化編程方法提供了非常大的多樣性,大大增加了代碼的重用機(jī)會(huì)。可以舉例進(jìn)一步說明這個(gè)問題,假定計(jì)算機(jī)上的一個(gè)高性能應(yīng)用程序是一輛一流賽車。如果使用傳統(tǒng)的編程技巧,這輛賽車就是一個(gè)單元。

如果要改進(jìn)該車,就必須替換整個(gè)單元,把它送回廠商,讓汽車專家升級(jí)它,或者購買一個(gè)新車。如果使用OOP技術(shù),就只需從廠商處購買新的引擎,自己按照說明替換它,而不必用鋼鋸切割車體。不過大部分的論點(diǎn)是,JavaScript并不是直接的面向?qū)ο蟮恼Z言,但是通過模擬可以做到很多面向?qū)ο笳Z言才能做到的事,如繼承,多態(tài),封裝,JavaScript都能干。

  1. //以下三種構(gòu)造對(duì)象的方法  
  2. //newObject,實(shí)例化一個(gè)Object  
  3. vara=newObject();  
  4. a.x=1,a.y=2;  
  5. //對(duì)象直接量  
  6. varb={x:1,y:2};  
  7. //定義類型  
  8. functionPoint(x,y){//類似于C#中的類  
  9. this.x=x;  
  10. this.y=y;  
  11. }  
  12. varp=newPoint(1,2);//實(shí)例化類 

第一種方法通過構(gòu)造基本對(duì)象直接添加屬性的方法來實(shí)現(xiàn),第二種和第一種差不多,可以看成是第一種方法的快捷表示法。第三種方法中,可以以”類“為基礎(chǔ),創(chuàng)造多個(gè)類型相同的對(duì)象。

#p#

三,對(duì)象屬性的封裝(公有和私有)

以例子來說明:

  1. functionList(){  
  2. varm_elements=[];//私有成員,在對(duì)象外無法訪問  
  3. m_elements=Array.apply(m_elements,arguments);  
  4. //此處模擬getter,使用時(shí)alist.length;  
  5. //等價(jià)于getName()方式:this.length=function(){returnm_elements.length;},使用時(shí)alist.length();  
  6. //公有屬性,可以通過"."運(yùn)算符或下標(biāo)來訪問  
  7. this.length={  
  8. valueOf:function(){  
  9. returnm_elements.length;  
  10. },  
  11. toString:function(){  
  12. returnm_elements.length;  
  13. }  
  14. }  
  15. //公有方法,此方法使用得alert(alist)相當(dāng)于alert(alist.toString())  
  16. this.toString=function(){  
  17. returnm_elements.toString();  
  18. }  
  19. //公有方法  
  20. this.add=function(){  
  21. m_elements.push.apply(m_elements,arguments);  
  22. }  
  23. //私有方法如下形式,這里涉及到了閉包的概念,接下來繼續(xù)說明  
  24. //varadd=function()或functionadd()  
  25. //{  
  26. //m_elements.push.apply(m_elements,arguments);  
  27. //}  
  28. }  
  29. varalist=newList(1,2,3);  
  30. dwn(alist);//=alert(alist.toString()),輸出1,2,3  
  31. dwn(alist.length);//輸出3  
  32. alist.add(4,5,6);  
  33. dwn(alist);//輸出1,2,3,4,5,6  
  34. dwn(alist.length);//輸出6 

四,屬性和方法的類型

JavaScript里,對(duì)象的屬性和方法支持4種不同的類型:privateproperty(私有屬性),dynamicpublicproperty(動(dòng)態(tài)公有屬性),staticpublicproperty/prototypeproperty(靜態(tài)公有屬性或原型屬性),staticproperty(靜態(tài)屬性或類屬性)。私有屬性對(duì)外界完全不具備訪問性,可以通過內(nèi)部的getter和setter(都是模擬);動(dòng)態(tài)公有屬性外界可以訪問,每個(gè)對(duì)象實(shí)例持有一個(gè)副本,不會(huì)相互影響;原型屬性每個(gè)對(duì)象實(shí)例共享唯一副本;類屬性不作為實(shí)例的屬性,只作為類的屬性。以下是例子:

  1. //動(dòng)態(tài)公有類型,靜態(tài)公有類型(原型屬性)  
  2. functionmyClass(){  
  3. varp=100;//privateproperty  
  4. this.x=10;//dynamicpublicproperty  
  5. }  
  6. myClass.prototype.y=20;  
  7. //要想成為高級(jí)JavaScript階段,prototype和閉包必須得理解和適當(dāng)應(yīng)用  
  8. myClass.z=30;//staticproperty  
  9.  
  10. vara=newmyClass();  
  11. dwn(a.p)//undefined  
  12. dwn(a.x)//10  
  13. dwn(a.y)//20  
  14. a.x=20;  
  15. a.y=40;  
  16. dwn(a.x);//20  
  17. dwn(a.y);//40  
  18. delete(a.x);//刪除對(duì)象a的屬性x  
  19. delete(a.y);//刪除對(duì)象a的屬性y  
  20. dwn(a.x);//undefined  
  21. dwn(a.y);//20靜態(tài)公有屬性y被刪除后還原為原型屬性y  
  22. dwn(a.z);//undefined類屬性無法通過對(duì)象訪問  
  23. dwn(myClass.z); 

五,原型(prototype)

這里只講部分,prototype和閉包都不是幾句話都能講清楚的,如果這里可以給你一些啟蒙,則萬幸矣。習(xí)語”照貓畫虎“,這里的貓就是原型,虎是類型,可以表示成:虎.prototype=某只貓or虎.prototype=new貓()。因?yàn)樵蛯傩悦總€(gè)對(duì)象實(shí)例共享唯一副本,所以當(dāng)實(shí)例中的一個(gè)調(diào)整了一個(gè)原型屬性的值時(shí),所有實(shí)例調(diào)用這個(gè)屬性時(shí)都將發(fā)生變化,這點(diǎn)需要注意,以下是原型關(guān)系的類型鏈:

  1. functionClassA(){  
  2. }  
  3. ClassA.prototype=newObject();  
  4. functionClassB(){  
  5. }  
  6. ClassB.prototype=newClassA();  
  7. functionClassC(){  
  8. }  
  9. ClassC.prototype=newClassB();  
  10. varobj=newClassC();  
  11. dwn(objinstanceofClassC);//true  
  12. dwn(objinstanceofClassB);//true  
  13. dwn(objinstanceofClassA);//true  
  14. dwn(objinstanceofObject);//true  
  15. 帶默認(rèn)值的Point對(duì)象:  
  16. functionPoint2(x,y){  
  17. if(x)this.x=x;  
  18. if(y)this.y=y;  
  19. }  
  20. //設(shè)定Point2對(duì)象的x,y默認(rèn)值為0  
  21. Point2.prototype.x=0;  
  22. Point2.prototype.y=0;  
  23. //p1是一個(gè)默認(rèn)(0,0)的對(duì)象  
  24. varp1=newPoint2();//可以寫成varp1=newPoint2也不會(huì)出錯(cuò),WHY  
  25. //p2賦值  
  26. varp2=newPoint2(1,2);  
  27. dwn(p1.x+","+p1.y);//0,0  
  28. dwn(p2.x+","+p2.y);//1,2  
  29. delete對(duì)象的屬性后,原型屬性將回到初始化的狀態(tài):  
  30. functionClassD(){  
  31. this.a=100;  
  32. this.b=200;  
  33. this.c=300 
  34. }  
  35. ClassD.prototype=newClassD();//將ClassD原有的屬性設(shè)為原型,包括其值  
  36. ClassD.prototype.reset=function(){//將非原型屬性刪除  
  37. for(vareachinthis){  
  38. deletethis[each];  
  39. }  
  40. }  
  41. vard=newClassD();  
  42. dwn(d.a);//100  
  43. d.a*=2;  
  44. d.b*=2;  
  45. d.c*=2;  
  46. dwn(d.a);//200  
  47. dwn(d.b);//400  
  48. dwn(d.c);//600  
  49. d.reset();//刪掉非原型屬性,所有回來原型  
  50. dwn(d.a);//100  
  51. dwn(d.b);//200  
  52. dwn(d.c);//300 

#p#

六,繼承

如果兩個(gè)類都是同一個(gè)實(shí)例的類型,那么它們之間存在著某種關(guān)系,我們把同一個(gè)實(shí)例的類型之間的泛化關(guān)系稱為繼承。C#和JAVA中都有這個(gè),具體的理解就不說了。在JavaScript中,并不直接從方法上支持繼承,但是就像前面說的,可以模擬。

方法可以歸納為四種:構(gòu)造繼承法,原型繼承法,實(shí)例繼承法和拷貝繼承法。融會(huì)貫通之后,還有混合繼續(xù)法,這是什么法,就是前面四種挑幾種混著來。以下例子來源于王者歸來,其中涉及到了apply,call和一些Array的用法,有興趣的可以自己在園子里搜索一下。

1,構(gòu)造繼續(xù)法例子:

  1. //定義一個(gè)Collection類型  
  2. functionCollection(size)  
  3. {  
  4. this.size=function(){returnsize};//公有方法,可以被繼承  
  5. }  
  6.  
  7. Collection.prototype.isEmpty=function(){//靜態(tài)方法,不能被繼承  
  8. returnthis.size()==0;  
  9. }  
  10. //定義一個(gè)ArrayList類型,它"繼承"Collection類型  
  11. functionArrayList()  
  12. {  
  13. varm_elements=[];//私有成員,不能被繼承  
  14. m_elements=Array.apply(m_elements,arguments);  
  15.  
  16. //ArrayList類型繼承Collection  
  17. this.base=Collection;  
  18. this.base.call(this,m_elements.length);  
  19.  
  20. this.add=function()  
  21. {  
  22. returnm_elements.push.apply(m_elements,arguments);  
  23. }  
  24. this.toArray=function()  
  25. {  
  26. returnm_elements;  
  27. }  
  28. }  
  29.  
  30. ArrayList.prototype.toString=function()  
  31. {  
  32. returnthis.toArray().toString();  
  33. }  
  34. //定義一個(gè)SortedList類型,它繼承ArrayList類型  
  35. functionSortedList()  
  36. {  
  37. //SortedList類型繼承ArrayList  
  38. this.base=ArrayList;  
  39. this.base.apply(this,arguments);  
  40.  
  41. this.sort=function()  
  42. {  
  43. vararr=this.toArray();  
  44. arr.sort.apply(arr,arguments);  
  45. }  
  46. }  
  47.  
  48. //構(gòu)造一個(gè)ArrayList  
  49. vara=newArrayList(1,2,3);  
  50. dwn(a);  
  51. dwn(a.size());//a從Collection繼承了size()方法  
  52. dwn(a.isEmpty);//但是a沒有繼承到isEmpty()方法  
  53.  
  54. //構(gòu)造一個(gè)SortedList  
  55. varb=newSortedList(3,1,2);  
  56. b.add(4,0);//b從ArrayList繼承了add()方法  
  57. dwn(b.toArray());//b從ArrayList繼承了toArray()方法  
  58. b.sort();//b自己實(shí)現(xiàn)的sort()方法  
  59. dwn(b.toArray());  
  60. dwn(b);  
  61. dwn(b.size());//b從Collection繼承了size()方法 

2,原型繼承法例子

  1. //定義一個(gè)Point類型  
  2. functionPoint(dimension)  
  3. {  
  4.  
  5. this.dimension=dimension;  
  6. }  
  7.  
  8. //定義一個(gè)Point2D類型,"繼承"Point類型  
  9. functionPoint2D(x,y)  
  10. {  
  11. this.x=x;  
  12. this.y=y;  
  13. }  
  14. Point2D.prototype.distance=function()  
  15. {  
  16. returnMath.sqrt(this.x*this.x+this.y*this.y);  
  17. }  
  18. Point2D.prototype=newPoint(2);//Point2D繼承了Point  
  19.  
  20. //定義一個(gè)Point3D類型,也繼承Point類型  
  21. functionPoint3D(x,y,z)  
  22. {  
  23. this.x=x;  
  24. this.y=y;  
  25. this.z=z;  
  26. }  
  27. Point3D.prototype=newPoint(3);//Point3D也繼承了Point  
  28.  
  29. //構(gòu)造一個(gè)Point2D對(duì)象  
  30. varp1=newPoint2D(0,0);  
  31. //構(gòu)造一個(gè)Point3D對(duì)象  
  32. varp2=newPoint3D(0,1,2);  
  33. dwn(p1.dimension);  
  34. dwn(p2.dimension);  
  35. dwn(p1instanceofPoint2D);//p1是一個(gè)Point2D  
  36. dwn(p1instanceofPoint);//p1也是一個(gè)Point  
  37. dwn(p2instanceofPoint);//p2是一個(gè)Point 

以上兩種方法是最常用。

3,實(shí)例繼承法例子

在說此法例子之前,說說構(gòu)造繼承法的局限,如下:

  1. functionMyDate()  
  2. {  
  3. this.base=Date;  
  4. this.base.apply(this,arguments);  
  5. }  
  6. vardate=newMyDate();  
  7. alert(date.toGMTString);//undefined,date并沒有繼承到Date類型,所以沒有toGMTString方法 

核心對(duì)象的某些方法不能被構(gòu)造繼承,原因是核心對(duì)象并不像我們自定義的一般對(duì)象那樣在構(gòu)造函數(shù)里進(jìn)行賦值或初始化操作換成原型繼承法呢?,如下:

  1. functionMyDate(){}  
  2. MyDate.prototype=newDate();  
  3. vardate=newMyDate();  
  4. alert(date.toGMTString);//'[object]'不是日期對(duì)象,仍然沒有繼承到Date類型! 

現(xiàn)在,換成實(shí)例繼承法:

  1. functionMyDate()  
  2. {  
  3. varinstance=newDate();//instance是一個(gè)新創(chuàng)建的日期對(duì)象  
  4. instance.printDate=function(){  
  5. document.write("<p>"+instance.toLocaleString()+"</p>");  
  6. }//對(duì)instance擴(kuò)展printDate()方法  
  7. returninstance;//將instance作為構(gòu)造函數(shù)的返回值返回  
  8. }  
  9. varmyDate=newMyDate();  
  10. dwn(myDate.toGMTString());//這回成功輸出了正確的時(shí)間字符串,看來myDate已經(jīng)是一個(gè)Date的實(shí)例了,繼承成功  
  11. myDate.printDate();//如果沒有returninstance,將不能以下標(biāo)訪問,因?yàn)槭撬接袑?duì)象的方法 

4,拷貝繼承法例子

  1. Function.prototype.extends=function(obj)  
  2. {  
  3. for(vareachinobj)  
  4. {  
  5. this.prototype[each]=obj[each];  
  6. //對(duì)對(duì)象的屬性進(jìn)行一對(duì)一的復(fù)制,但是它又慢又容易引起問題  
  7. //所以這種“繼承”方式一般不推薦使用  
  8. }  
  9. }  
  10. varPoint2D=function(){  
  11. //……  
  12. }  
  13. Point2D.extends(newPoint())  
  14. {  
  15. //……  

這種繼承法似乎是用得很少的。

5,混合繼承例子

  1. functionPoint2D(x,y)  
  2. {  
  3. this.x=x;  
  4. this.y=y;  
  5. }  
  6. functionColorPoint2D(x,y,c)  
  7. {  
  8. Point2D.call(this,x,y);//這里是構(gòu)造繼承,調(diào)用了父類的構(gòu)造函數(shù)  
  9. //從前面的例子看過來,這里等價(jià)于  
  10. //this.base=Point2D;  
  11. //this.base.call(this,x,y);  
  12. this.color=c;  
  13. }  
  14. ColorPoint2D.prototype=newPoint2D();//這里用了原型繼承,讓ColorPoint2D以Point2D對(duì)象為原型 

 

【編輯推薦】

  1. 深入淺出JavaScript內(nèi)存泄漏
  2. 拔開云霧見明月 透析JavaScript定時(shí)機(jī)制
  3. 揭開JavaScript閉包的真實(shí)面目
  4. JavaScript中的函數(shù)式編程實(shí)踐
  5. 三大秘訣助你輕松搞定JavaScript
責(zé)任編輯:王曉東 來源: 博客園
相關(guān)推薦

2015-04-30 10:12:13

開源云平臺(tái)OpenStack

2014-03-21 15:30:06

產(chǎn)品經(jīng)理PM能力

2017-08-09 14:49:03

WebHTTPS瀏覽器

2013-01-15 10:09:43

Windows Ser

2016-07-25 12:58:07

SDN路由故障排查

2014-07-09 09:06:33

SDN自動(dòng)化

2024-10-31 11:49:41

Kafka管理死信隊(duì)列

2013-02-19 09:21:01

Win 8

2020-10-30 09:33:01

分庫分表數(shù)據(jù)庫

2016-07-04 08:01:46

2021-03-29 13:00:50

代碼替換開發(fā)

2013-10-08 10:01:03

惠普開源SDN

2018-10-19 11:15:34

云計(jì)算互聯(lián)網(wǎng)數(shù)據(jù)中心

2014-04-23 15:13:42

2018-04-12 11:20:57

顯示器配件參數(shù)

2014-08-25 10:17:54

數(shù)據(jù)中心管理

2020-03-26 10:41:02

API網(wǎng)關(guān)大公司

2021-01-03 19:54:53

Python數(shù)據(jù)科學(xué)數(shù)據(jù)分析

2021-01-04 09:55:45

Python開發(fā)數(shù)據(jù)

2012-10-10 13:23:24

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 在线欧美一区 | 亚洲综合视频 | 日韩精品视频网 | 欧美国产日韩在线观看成人 | 欧美色综合一区二区三区 | 国产精品久久国产精品99 | 国产视频一区二区在线观看 | 99精品视频免费观看 | 亚洲精品久久久久久久不卡四虎 | 日本亚洲一区二区 | 久久综合av | 午夜视频在线免费观看 | 欧美一级黄色片免费观看 | 不卡一区二区三区四区 | 精品视频www | 欧美性猛片aaaaaaa做受 | 午夜精品 | 天堂男人av | 成人免费淫片aa视频免费 | 久久亚洲国产 | 午夜精品网站 | 精品一区久久 | 久草新在线 | 91免费版在线观看 | 国产成人免费视频 | 免费视频一区 | 欧美视频中文字幕 | 最新日韩精品 | 麻豆精品国产91久久久久久 | 男人天堂社区 | 国产激情片在线观看 | 中文字幕在线电影观看 | 免费的av网站 | 免费在线观看91 | 欧美激情精品久久久久久 | 色呦呦网站 | 久久大陆 | 亚洲视频免费在线观看 | 秋霞a级毛片在线看 | 久久久久国产一区二区三区四区 | 亚洲人成人一区二区在线观看 |