日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
面向?qū)ο蟮腏avaScript基本知識(shí)指南大全

由于jQuery和MooTools等精心開(kāi)發(fā)的庫(kù),JavaScript已成為前端開(kāi)發(fā)的基礎(chǔ)。不過(guò),我們要留意這些優(yōu)秀庫(kù)中所運(yùn)用的較高級(jí)概念,這點(diǎn)極其重要。原因何在?因?yàn)樽鳛閃eb開(kāi)發(fā)人員,對(duì)待學(xué)習(xí)最新的編程趨勢(shì)和試圖把那些趨勢(shì)推向極致,我們必須予以一視同仁。要不然,Web開(kāi)發(fā)領(lǐng)域就不會(huì)出現(xiàn)創(chuàng)新。所以,我們不妨花點(diǎn)時(shí)間來(lái)了解JavaScript面向?qū)ο缶幊痰幕局R(shí),包括類(lèi)、繼承和范圍。

類(lèi)

在我們學(xué)習(xí)如何把類(lèi)實(shí)施到代碼中之前,不妨討論一下類(lèi)是什么、為什么有必要學(xué)習(xí)/使用類(lèi)。

正如Java文檔聲明的那樣:“類(lèi)是用來(lái)創(chuàng)建一個(gè)個(gè)對(duì)象的藍(lán)圖。”這藍(lán)圖就像造房子過(guò)程中所用的實(shí)際藍(lán)圖。建造人員使用藍(lán)圖來(lái)評(píng)估房子有什么樣的屬性,房子會(huì)有什么樣的功能。類(lèi)是表示對(duì)象屬性的一種很方便的方式,無(wú)論這對(duì)象是房子、汽車(chē)還是人。當(dāng)存在的某個(gè)對(duì)象不止一個(gè)時(shí),類(lèi)就變得特別有用。

比如說(shuō),我們不使用類(lèi)來(lái)比較一下兩個(gè)實(shí)際的對(duì)象。這體現(xiàn)了程序思考過(guò)程,而不是面向?qū)ο蟮乃伎歼^(guò)程。我們將描述一個(gè)名叫Rob的男子和一個(gè)名為Emillee的小女孩。我們必須假定我們對(duì)人體一無(wú)所知,因?yàn)槲覀儧](méi)有藍(lán)圖(類(lèi))可供使用。

Rob:

1. Rob在身體的上部有兩個(gè)橢圓形的結(jié)構(gòu),相隔幾英寸。這些橢圓形結(jié)構(gòu)有一個(gè)黑色背景,中間是棕色。

2. Rob有兩個(gè)與地面相對(duì)平行的結(jié)構(gòu),似乎表明了人體中最垂直的部分,這仍是身體基部的一部分。

3. Rob有兩個(gè)附屬物,從另外兩個(gè)附屬物延伸過(guò)來(lái)。這些似乎可用來(lái)抓取物件。它們似乎比較大。

4. Rob高度約6英尺。

5. Rob無(wú)意識(shí)地吸入氧,把氧轉(zhuǎn)換成二氧化碳。

Emilee:

1. Emillee在身體的上部有兩個(gè)橢圓形的結(jié)構(gòu),相隔幾英寸。這些橢圓形結(jié)構(gòu)有一個(gè)黑色背景,中間是藍(lán)色。

2. Emillee有兩個(gè)與地面相對(duì)平行的結(jié)構(gòu),似乎表明了人體中最垂直的部分,這仍是身體基部的一部分。

3. Emillee有兩個(gè)附屬物,從另外兩個(gè)附屬物延伸過(guò)來(lái)。這些似乎可用來(lái)抓取物件。它們似乎比較小。

4. Emillee高度約1.5英尺。

5. Emillee無(wú)意識(shí)地吸入氧,把氧轉(zhuǎn)換成二氧化碳。

單單描述一個(gè)人的1)眼睛、2)肩膀、3)雙手、4)身高和5)呼吸行為就有大量的工作要做。要注意:我們不得不兩次給出幾乎一模一樣的看法,因?yàn)槲覀儧](méi)有藍(lán)圖可供使用。雖然描述兩個(gè)人不是太費(fèi)勁,但是如果我們想要描述100個(gè)人、1000個(gè)人或者100萬(wàn)個(gè)人,怎么辦?肯定有一種更高效的方法來(lái)描述有著類(lèi)似屬性的對(duì)象:這正是類(lèi)的亮點(diǎn)。

我們不妨使用面向?qū)ο蟮睦砟?,重新考慮前一個(gè)例子。由于我們描述的是男子和小女孩,我們知道他們都是人類(lèi)。所以不妨先為人類(lèi)創(chuàng)建一個(gè)簡(jiǎn)單的藍(lán)圖。

人類(lèi):

1. 身體的上部有兩個(gè)橢圓形的結(jié)構(gòu)。這些橢圓形結(jié)構(gòu)有一個(gè)黑色背景,中間顏色不一樣。我們稱(chēng)之為眼睛。

2. 有兩個(gè)與地面相對(duì)平行的結(jié)構(gòu),似乎表明了人體中最垂直的部分,這仍是身體基部的一部分。我們稱(chēng)之為肩膀。

3. 有兩個(gè)附屬物,從另外兩個(gè)附屬物延伸過(guò)來(lái)。這些似乎可用來(lái)抓取物件。它們的大小不一樣。我們稱(chēng)之為雙手。

4. 視年齡及其他因素而定,高度不一樣。我們稱(chēng)之為身高。

5. 無(wú)意識(shí)地吸入氧,并把氧轉(zhuǎn)換成二氧化碳。我們稱(chēng)之為呼吸。

于是我們已聲明,人類(lèi)的屬性是,他們有眼睛,有肩膀,有雙手,有身高。我們還已聲明,這些屬性可能不一樣。定義了人類(lèi)的藍(lán)圖后,并且聲明了Rob和Emillee是人類(lèi)后,我們可以將已經(jīng)知道的關(guān)于人類(lèi)的屬性運(yùn)用到Rob和Emillee。

Rob是人類(lèi)。

1. Rob有棕色的眼睛

2. Rob有肩膀

3. Rob有大大的雙手

4. Rob身高6英寸

5. Rob會(huì)呼吸

Emillee是人類(lèi)。

1. Emillee有藍(lán)色的眼睛

2. Emillee有肩膀

3. Emillee有小小的雙手

4. Emillee身高1.5英尺

5. Emillee會(huì)呼吸

我們只要明確聲明Rob和Emillee是人類(lèi),就可以把與人類(lèi)有關(guān)的屬性和功能直接運(yùn)用到Rob和Emillee。這讓我們可以避免重新定義身體的所有部位,同時(shí)讓我們可以高效地描述這兩個(gè)對(duì)象之間的重要區(qū)別。

下面是關(guān)于類(lèi)及對(duì)象(名為類(lèi)的實(shí)例)的幾個(gè)例子,以便你明白兩者之間的關(guān)系。

類(lèi)Student(學(xué)生)

◆ 屬性:年級(jí)、年齡、出生日期和學(xué)生身份標(biāo)志(SSID)

◆ 功能:計(jì)算年級(jí)平均成績(jī)、查看缺課情況、更新操行評(píng)語(yǔ)

類(lèi)Employee(員工)

◆ 屬性:雇主身份識(shí)別號(hào)(EIN)、小時(shí)工資、聯(lián)系號(hào)碼、保險(xiǎn)

◆ 功能:設(shè)定薪水、查看工作效率和獲取簡(jiǎn)歷

類(lèi)Computer(電腦)

◆ 屬性:處理器、主機(jī)、顯示器

◆ 功能:開(kāi)機(jī)、關(guān)機(jī)和重啟

好了,我們已明白了類(lèi)背后的概念,不妨把所知道的東西運(yùn)用到JavaScript。與包括PHP和C++在內(nèi)的語(yǔ)言不一樣,JavaScript沒(méi)有類(lèi)數(shù)據(jù)類(lèi)型。不過(guò),如果我們借助JavaScript的靈活性,就很容易使用函數(shù)來(lái)模擬類(lèi)。

我們以前面一個(gè)例子為例,使用類(lèi)來(lái)表示學(xué)生。

創(chuàng)建一個(gè)類(lèi)時(shí),你必須做兩件事:必須知道這個(gè)類(lèi)有什么屬性/函數(shù)(又叫方法);你需要用一個(gè)值來(lái)初始化屬性。

 
 
 
  1. function Student(name, gender, age, grade, teacher) 
  2.     { 
  3.         this.name = name; 
  4.         this.gender = gender; 
  5.         this.age = age; 
  6.         this.grade = grade; 
  7.         this.teacher = teacher; 
  8.     } 
  9.     var bob = new Student("bob", "male", 15, 10, "Marlow"); 
  10.     alert(bob.age); //輸出15 
  11.     var susan = new Student("susan", "female", 10, 5, "Gresham"); 
  12.     alert(susan.gender); //輸出 'female' 

我們可以從這個(gè)例子中看出,類(lèi)的實(shí)例使用新的運(yùn)算符來(lái)進(jìn)行初始化。類(lèi)的屬性和方法使用. (dot)運(yùn)算符來(lái)訪問(wèn)。所以為了獲得名為bob的Student類(lèi)實(shí)例的屬性年齡,我們只要使用bob.age。同樣,我們創(chuàng)建了Student類(lèi)的一個(gè)實(shí)例,把它分配給susan。為了獲得susan的性別,我們只要使用susan.gender。類(lèi)在代碼可讀性方面帶來(lái)了巨大的好處:你不需要有任何編程經(jīng)驗(yàn),就能推斷出bob.age是bob的年齡。

不過(guò),前一個(gè)例子有兩個(gè)不好(但很容易修復(fù))的缺點(diǎn)。

1)任何語(yǔ)句都可以訪問(wèn)類(lèi)屬性

2)參數(shù)必須以一定的次序來(lái)傳遞

#p#

確保屬性值的私有性

請(qǐng)注意:在前一個(gè)例子中,我們只要調(diào)用bob.age,就能獲得bob.age的值。此外,我們可以在程序中任何地方將bob.age設(shè)成自己喜歡的任何值。

 
 
 
  1. var bob = new Student("bob", "male", 15, 10, "Marlow"); 
  2.     alert(bob.age); //輸出15 
  3.     bob.age = 9; 
  4.     alert(bob.age); //輸出9; 

看起來(lái)沒(méi)有害處,是不是?那么請(qǐng)考慮這個(gè)例子。

 
 
 
  1. var bob = new Student("bob", "male", 15, 10, "Marlow"); 
  2. alert(bob.age); //輸出15 
  3. bob.age = -50; 
  4. alert(bob.age); //輸出-50; 

我們看到了年齡是負(fù)值:這在邏輯上不一致。我們只要使用私有變量(private variable)這個(gè)概念,就可以防止諸如此類(lèi)的問(wèn)題、確保數(shù)據(jù)的完整性。私有變量是只能在類(lèi)本身里面訪問(wèn)的變量。雖然JavaScript再次沒(méi)有用于確保變量私有性的保留字,但是JavaScript為我們提供了創(chuàng)造同樣效果的工具。

 
 
 
  1. function Student(name, gender, age, grade, teacher) 
  2.     { 
  3.         var studentName = name; 
  4.         var studentGender = gender; 
  5.         var studentGrade = grade; 
  6.         var studentTeacher = teacher; 
  7.         var studentAge = age; 
  8.         this.getAge = function() 
  9.         { 
  10.             return studentAge; 
  11.         }; 
  12.         this.setAge = function(val) 
  13.         { 
  14.             studentAge = Math.abs(val); //使用絕對(duì)值,確保年齡是正值 
  15.         }; 
  16.     } 
  17.     var bob = new Student("bob", "male", 15, 10, "Marlow"); 
  18.     alert(bob.studentAge); //未定義,因?yàn)槟挲g在類(lèi)定義中受私有保護(hù) 
  19.     alert(bob.getAge()); //輸出15 
  20.     bob.setAge(-20); 
  21.     alert(bob.getAge()); //輸出20 

通過(guò)使用變量聲明,而不是直接為類(lèi)賦予屬性,我們保護(hù)了年齡數(shù)據(jù)的完整性。由于JavaScript使用了函數(shù)范圍,我們的類(lèi)里面聲明的變量在該類(lèi)外面是無(wú)法訪問(wèn)的,除非由該類(lèi)里面的函數(shù)明確返回。方法this.getAge將學(xué)生年齡返回到調(diào)用環(huán)境,它名為訪問(wèn)器方法(Accessor method)。訪問(wèn)器方法返回屬性的值,那樣該值就可以在類(lèi)的外面使用,而不影響類(lèi)里面的值。按照約定,訪問(wèn)器方法的前綴通常是“get”這個(gè)字。方法this.setAge名為更改器方法(Mutator method)。其目的是,改變屬性的值,保護(hù)完整性。

我們已看到了在類(lèi)里面使用訪問(wèn)器方法和更改器方法來(lái)保護(hù)數(shù)據(jù)完整性的好處。不過(guò),為每個(gè)屬性創(chuàng)建訪問(wèn)器方法帶來(lái)了極其冗長(zhǎng)的代碼。

 
 
 
  1. function Student(name, gender, age, grade, teacher) 
  2.     var studentName = name; 
  3.     var studentGender = gender; 
  4.     var studentGrade = grade; 
  5.     var studentTeacher = teacher; 
  6.     var studentAge = age; 
  7.     this.getName = function() 
  8.     { 
  9.         return studentName; 
  10.     }; 
  11.     this.getGender = function() 
  12.     { 
  13.         return studentGender; 
  14.     }; 
  15.     this.getGrade = function() 
  16.     { 
  17.         return studentGrade; 
  18.     }; 
  19.     this.getTeacher = function() 
  20.     { 
  21.         return studentTeacher; 
  22.     }; 
  23.     this.getAge = function() 
  24.     { 
  25.         return studentAge; 
  26.     }; 
  27.     this.setAge = function(val) 
  28.     { 
  29.         studentAge = Math.abs(val); //使用絕對(duì)值,確保年齡是正值 
  30.     }; 
  31. var bob = new Student("bob", "male", 15, 10, "Marlow"); 
  32. alert(bob.studentGender); //未定義,因?yàn)樾詣e在類(lèi)定義中受私有保護(hù) 
  33. alert(bob.getGender()); //輸出 'male' 

教我C++的教授總是說(shuō):“如果你發(fā)現(xiàn)自己反復(fù)輸入相同的代碼,這表明你的做法不對(duì)?!钡拇_,有更高效的方法可以為每個(gè)屬性創(chuàng)建訪問(wèn)器方法。此外,這種機(jī)制還不需要以特定次序來(lái)調(diào)用函數(shù)參數(shù)。

動(dòng)態(tài)創(chuàng)建的訪問(wèn)器方法

這個(gè)演示來(lái)自John Resig所寫(xiě)的《專(zhuān)業(yè)JavaScript技巧》一書(shū)(我強(qiáng)烈建議各位讀一讀。前三章就非常值得一讀)。

 
 
 
  1. function Student( properties ) 
  2.     { 
  3.         var $this = this;  //將類(lèi)范圍存儲(chǔ)到名為$this的變量中 
  4.         //迭代處理對(duì)象的屬性 
  5.         for ( var i in properties ) 
  6.         { 
  7.             (function(i) 
  8.             { 
  9.                 // 動(dòng)態(tài)創(chuàng)建訪問(wèn)器方法 
  10.                 $this[ "get" + i ] = function() 
  11.                 { 
  12.                     return properties[i]; 
  13.                 }; 
  14.             })(i); 
  15.         } 
  16.     } 
  17.     // 創(chuàng)建一個(gè)新的用戶對(duì)象實(shí)例,并傳遞屬性的對(duì)象 
  18.     var student = new Student( 
  19.     { 
  20.         Name: "Bob", 
  21.         Age: 15, 
  22.         Gender: "male" 
  23.     }); 
  24.     alert(student.name); //因?qū)傩允撬接械亩炊x 
  25.     alert(student.getName()); //輸出 "Bob" 
  26.     alert(student.getAge()); //輸出15 
  27.     alert(student.getGender()); //輸出 "male" 

通過(guò)實(shí)施這個(gè)技巧,我們不但確保自己的屬性是私有的,而且不需要按次序來(lái)指定參數(shù)。下面的類(lèi)實(shí)例化都相同:

 
 
 
  1. var student = new Student( 
  2.     { 
  3.         Name: "Bob", 
  4.         Age: 15, 
  5.         Gender: "male" 
  6.     }); 
  7.     var student = new Student( 
  8.     { 
  9.         Age: 15, 
  10.         Name: "Bob", 
  11.         Gender: "male" 
  12.     }); 
  13.     var student = new Student( 
  14.     { 
  15.         Gender: "male", 
  16.         Age: 15, 
  17.         Name: "Bob" 
  18.     }); 

#p#

繼承

在這篇文章中,我使用“類(lèi)”這個(gè)術(shù)語(yǔ)極其寬松。如前所述,JavaScript沒(méi)有類(lèi)實(shí)體,但是后面仍可以跟類(lèi)的模式。JavaScript與其他面向?qū)ο笳Z(yǔ)言的區(qū)別主要在于繼承模型。C++和Java體現(xiàn)了基于類(lèi)的繼承或傳統(tǒng)繼承。另一方面,JavaScript體現(xiàn)了原型繼承(Prototypal Inheritance)。在其他面向?qū)ο笳Z(yǔ)言中,類(lèi)是一個(gè)實(shí)際的數(shù)據(jù)類(lèi)型,表示創(chuàng)建對(duì)象的藍(lán)圖。在JavaScript中,雖然我們可以使用函數(shù)來(lái)模擬對(duì)象藍(lán)圖,但是它們實(shí)際上本身就是對(duì)象。然后,這些對(duì)象用作其他對(duì)象的模型(又叫原型),可以參閱文章《JavaScript原型繼承》(http://www.webreference.com/programming/javascript/prototypal_inheritance/index.html)。

運(yùn)用原型繼承這個(gè)概念讓我們得以創(chuàng)建“子類(lèi)”,即繼承另一個(gè)對(duì)象的屬性的對(duì)象。如果我們想使用另一個(gè)對(duì)象的稍有一些變動(dòng)的方法,這就變得極其有用。

以類(lèi)Employee(員工)為例。假設(shè)我們有兩種類(lèi)型的員工:一種基于薪水,一種基于傭金。這些員工類(lèi)型會(huì)有許多相似的屬性。比如說(shuō),不管某員工通過(guò)傭金獲得收入還是通過(guò)薪水獲得收入,該員工都有名稱(chēng)。不過(guò),對(duì)基于傭金的員工和基于薪水的員工來(lái)說(shuō),收入方式完全不一樣。下面這個(gè)例子體現(xiàn)了這個(gè)概念:

 
 
 
  1. function Worker() 
  2.     this.getMethods = function(properties, scope) 
  3.     { 
  4.         var $this = scope;  //將類(lèi)范圍存儲(chǔ)到名為$this的變量中 
  5.         //迭代處理對(duì)象的屬性 
  6.         for ( var i in properties ) 
  7.         { 
  8.             (function(i) 
  9.             { 
  10.                 // 動(dòng)態(tài)創(chuàng)建訪問(wèn)器方法 
  11.                 $this[ "get" + i ] = function() 
  12.                 { 
  13.                     return properties[i]; 
  14.                 }; 
  15.             //動(dòng)態(tài)地創(chuàng)建一個(gè)分析整數(shù),并確保是正值的更改器方法。 
  16.             $this[ "set" + i ] = function(val) 
  17.             { 
  18.                 if(isNaN(val)) 
  19.                 { 
  20.                     properties[i] = val; 
  21.                 } 
  22.                 else 
  23.                 { 
  24.                     properties[i] = Math.abs(val); 
  25.                 } 
  26.             }; 
  27.             })(i); 
  28.         } 
  29.     }; 
  30. // CommissionWorker "子類(lèi)"和WageWorker "子類(lèi)" 
  31. //繼承Worker的屬性和方法。 
  32. CommissionWorker.prototype = new Worker(); 
  33. WageWorker.prototype = new Worker(); 
  34. function CommissionWorker(properties) 
  35.     this.getMethods(properties, this); 
  36.     //計(jì)算收入 
  37.     this.getIncome = function() 
  38.     { 
  39.         return properties.Sales * properties.Commission; 
  40.     } 
  41. //要求有下列屬性:薪水、每周小時(shí)數(shù)、每年周數(shù) 
  42. function WageWorker(properties) 
  43.     this.getMethods(properties, this); 
  44.     //計(jì)算收入 
  45.     this.getIncome = function() 
  46.     { 
  47.         return properties.Wage * properties.HoursPerWeek * properties.WeeksPerYear; 
  48.     } 
  49. var worker = new WageWorker( 
  50.     Name: "Bob", 
  51.     Wage: 10, 
  52.     HoursPerWeek: 40, 
  53.     WeeksPerYear: 48 
  54. }); 
  55. alert(worker.wage); //未定義。薪水是私有屬性。 
  56. worker.setWage(20); 
  57. alert(worker.getName());   //輸出 "Bob" 
  58. alert(worker.getIncome()); //輸出 38,400 (20*40*48) 
  59. var worker2 = new CommissionWorker( 
  60.     Name: "Sue", 
  61.     Commission: .2, 
  62.     Sales: 40000 
  63. }); 
  64. alert(worker2.getName());   //輸出 "Sue" 
  65. alert(worker2.getIncome()); //輸出8000(2% 乘40,000) 

前一個(gè)例子中最重要的兩個(gè)語(yǔ)句是:

 
 
 
  1. CommissionWorker.prototype = new Worker(); 
  2. WageWorker.prototype = new Worker(); 

這聲明,對(duì)新的CommissionWorker或新的WageWorker對(duì)象的每個(gè)實(shí)例而言,Worker的屬性和方法將傳遞到那些新對(duì)象。如果需要的話,這些方法和屬性可以在“子類(lèi)”定義里面被覆蓋寫(xiě)入。

范圍

JavaScript體現(xiàn)了所謂的函數(shù)范圍。這意味著,函數(shù)中聲明的變量在函數(shù)(變量來(lái)自該函數(shù))外面最初是無(wú)法訪問(wèn)的。不過(guò),在語(yǔ)句塊中(如條件語(yǔ)句),可以對(duì)調(diào)用環(huán)境進(jìn)行變量聲明或改動(dòng)。

 
 
 
  1. var car = "Toyota"; 
  2.     if(car == "Toyota") 
  3.     { 
  4.         car = "Toyota - We never stop...and you won't either."; 
  5.     } 
  6.     alert(car); //輸出Toyota——我們從未停上,你也如此。 
  7.     car = "Toyota"; //將汽車(chē)設(shè)回成原始值。 
  8.     function makeFord(car) 
  9.     { 
  10.         car = "Ford"; 
  11.     } 
  12.     makeFord(car); 
  13.     alert(car); //輸出"Toyota",因?yàn)槠?chē)在函數(shù)范圍中已改動(dòng)。 

不過(guò),如果你想要改動(dòng)值的函數(shù),可以將對(duì)象作為參數(shù)來(lái)傳遞,并改動(dòng)對(duì)象的屬性。

 
 
 
  1. var car = new Object(); 
  2.     car.brand = "Toyota" 
  3.     function makeFord(car) 
  4.     { 
  5.         car.brand = "Ford"; 
  6.     } 
  7.     makeFord(car); 
  8.     alert(car.brand); //輸出“Ford” 

這名為“通過(guò)調(diào)用”傳遞,將值傳遞給函數(shù)。只有你在類(lèi)里面創(chuàng)建方法,又知道對(duì)象含有什么屬性,我一般才會(huì)建議采用通過(guò)調(diào)用傳遞。

現(xiàn)在你已經(jīng)掌握了運(yùn)用到JavaScript的面向?qū)ο蟮幕局R(shí)。運(yùn)用這些原則,就可以為你在將來(lái)的開(kāi)發(fā)項(xiàng)目簡(jiǎn)化代碼。

原文:http://www.1stwebdesigner.com/design/object-oriented-basics-javascript/


網(wǎng)站名稱(chēng):面向?qū)ο蟮腏avaScript基本知識(shí)指南大全
網(wǎng)頁(yè)路徑:http://m.5511xx.com/article/ccdpcpg.html