翻譯說明:本文是我從Prado框架的《快速入門指南》翻譯中摘錄出來的,感覺對JavaScript的學(xué)習(xí)很有幫助,特貼出備忘。
Javascript簡介本指引基于Sergio Pereira的 Quick guide to somewhat advanced JavaScript tour of some OO features。嘿,我不知道你能那樣做如果你是一個Web開發(fā)者而且與我來自同一個地方,你也許在你的Web頁面中使用過相當多的Javascript,大部分用來作用戶界面(UI)的粘合。 直到現(xiàn)在,我才知道Javascript具有比我過去使用的更多的面向?qū)ο竽芰Γ皇俏覜]有如我所需的去使用它。當瀏覽器開始支持更標準的Javascript和DOM的功能集時,要為客戶端上的運行而編寫更復(fù)雜和多功能的代碼就變得可行了。它助長了AJAX現(xiàn)象的產(chǎn)生。 當我們都開始學(xué)習(xí)它適合編寫什么酷的AJAX應(yīng)用時,我們開始關(guān)注到我們過去知道的Javascript不過只是冰山一角而已。我們現(xiàn)在知道Javascript不僅僅被用于象輸入校驗等簡單的用戶界面雜務(wù)和其他瑣碎任務(wù)?,F(xiàn)在的客戶端代碼更高級和分層,更象一個真正的桌面應(yīng)用或一個客戶端-服務(wù)器的富客戶端。我們在其中看到了過去僅在服務(wù)器端的代碼中見到的類庫、對象模型、繼承關(guān)系、模式和許多其他的東西。 突然在我們能講到的許多方面被放到了比以前更高的位置。要為新的Web編寫應(yīng)用,我們必需提高我們的Javascript水平來跟上它而且要更加熟練。假如你嘗試運用許多現(xiàn)有的javascript庫,如:Prototype.js、Scriptaculous、moo.fx、Behaviour、YUI等,你最終會發(fā)現(xiàn)自己要閱讀JS代碼?;蛟S因為你想要學(xué)習(xí)它們?nèi)绾螌崿F(xiàn),或因為你的好奇,或通常因為那是知道如何使用它的唯一辦法,大多數(shù)這些庫象是不太注重文檔。無論個案會是什么,假如你之前不了解那樣的東西,你將要面對一些引起恐慌的外部技術(shù)。 本文的目的正好是解說許多我們還不熟悉的構(gòu)造類型。 JSON (JavaScript Object Notation-Javascript對象表示法)Javascript對象表示法(JSON),是圍繞AJAX主題突然出現(xiàn)的一個新的時髦詞。JSON,簡單的說就是一種在Javascript中定義對象的方法。讓我們馬上來看看一個實例并體會它如何簡單。 var myPet = { color: 'black', leg_count: 4, communicate: function(repeatCount){ for(i=0;i<repeatCount;i++) alert('Woof!');} }; 就讓我們加入些許格式讓它看起來象我們平常所認識的那樣: var myPet = { color: 'black', legCount: 4, communicate: function(repeatCount) { for(i=0;i<repeatCount;i++) alert('Woof!'); } }; 在這我們創(chuàng)建了一個帶兩個屬性(color和legCount)和一個方法(communicate)的對象引用。不難發(fā)現(xiàn),該對象的屬性和方法用一個逗號區(qū)隔的列表來定義。每個成員通過名稱來引入,接著是冒號和定義。對于屬性來說很容易,僅僅是屬性值。方法通過指派一個匿名函數(shù)來創(chuàng)建,我們下面會更好地說明。在該對象被創(chuàng)建并指派給變量myPet之后,我們可以如下使用它: alert('my pet is ' + myPet.color); alert('my pet has ' + myPet.legCount + ' legs'); //if you are a dog, bark three times: myPet.communicate(3); You'll see JSON used pretty much everywhere in JS these days, as arguments to functions, as return values, as server responses (in strings,) etc. 你想說什么?函數(shù)也是一個對象?對于開發(fā)者來說這可能與眾不同,但在JS中一個函數(shù)也是一個對象。你可以象參數(shù)一樣把一個函數(shù)傳送給另一個函數(shù),就象你可以傳送一個字符串一樣。這些被廣泛應(yīng)用而且非常便利。 看看這個實例。我們將把函數(shù)傳送到另一個使用它們的函數(shù)去。 var myDog = { bark: function() { alert('Woof!'); } }; var myCat = { meow: function() { alert('I am a lazy cat. I will not meow for you.'); } }; function annoyThePet(petFunction) { //let's see what the pet can do petFunction(); } //annoy the dog: annoyThePet(myDog.bark); //annoy the cat: annoyThePet(myCat.meow); 注意,我們把沒有添加"()"的myDog.bark和myCat.meow傳送給它們。假如我們那樣做了,我們不是傳送函數(shù),而是調(diào)用那些方法并傳送它們的返回值,這里的兩個個案中都未定義。 要是你想另我的懶貓起來嗥叫,你可以簡單地這樣做: myCat.meow = myDog.bark; myCat.meow(); //alerts 'Woof!' 數(shù)組、項目和對象成員在JS中下列兩行做了同樣的事。 var a = new Array(); var b = []; 正如我確定你已經(jīng)知道的那樣,你可以通過使用方括號在一個數(shù)組中訪問個別項目: var a = ['first', 'second', 'third']; var v1 = a[0]; var v2 = a[1]; var v3 = a[2]; 但你還不限于數(shù)字索引。你可以通過使用它的名字以字符串來訪問一個JS對象的任何成員。下面的例子創(chuàng)建了一個空對象,并通過名字加入了一些成員。 var obj = {}; //new, empty object obj['member_1'] = 'this is the member value'; obj['flag_2'] = false; obj['some_function'] = function(){ /* do something */}; 上述代碼的作用與下面的相同: var obj = { member_1:'this is the member value', flag_2: false, some_function: function(){ /* do something */} }; 在許多情形下,在JS中對象的概念和關(guān)聯(lián)的數(shù)組(雜湊)沒有區(qū)別。下面兩行代碼都做了同樣的事情。 obj.some_function(); obj['some_function'](); 關(guān)于對象已經(jīng)夠了,我現(xiàn)在能有一個類了嗎?面向?qū)ο缶幊陶Z言的巨大力量來源于類的使用。我不認為僅應(yīng)用我之前使用其他語言的經(jīng)驗就能推測出在JS中如何定義類。這由你自己來判斷。 //defining a new class called Pet var Pet = function(petName, age) { this.name = petName; this.age = age; }; //let's create an object of the Pet class var famousDog = new Pet('Santa\'s Little Helper', 15); alert('This pet is called ' + famousDog.name); 讓我們看看如何加入一個方法到我們的Pet類。我們將使用所有類都具有的prototype屬性。prototype屬性是一個包含任何對象的類會具有的所有成員的對象。甚至默認的JS類,如String、Number和Date擁有一個的prototype對象,它能讓我們可以添加方法和屬性并使那個類的任何對象自動獲取這個新成員。 Pet.prototype.communicate = function() { alert('I do not know what I should say, but my name is ' + this.name); }; 那就是一個類似于prototype.js的庫會派上用場的時候。如果我們使用prototype.js,我們能使我們的代碼看起來更清晰(至少在我看來是這樣)。 var Pet = Class.create(); Pet.prototype = { //our 'constructor' initialize: function(petName, age) { this.name = petName; this.age = age; }, communicate: function() { alert('I do not know what I should say, but my name is ' + this.name); } }; 函數(shù)作為參數(shù),一個有趣的模式假如你從來沒有接觸過支持閉合的語言,你也許會發(fā)現(xiàn)下面的慣用法太令人震驚了。 var myArray = ['first', 'second', 'third']; myArray.each( function(item, index) { alert('The item in the position #' + index + ' is:' + item); }); 哇!在你斷定我已經(jīng)離題太遠并且想轉(zhuǎn)去比這篇更好點的文章之前,讓我們在這解釋一下要繼續(xù)干些什么。 首先,在上述實例中我們使用了prototype.js庫,它添加了each函數(shù)到Array類。該each函數(shù)接到一個函數(shù)對象的參數(shù)。這個函數(shù)對于數(shù)組中的每個項目都將被依次調(diào)用一次,對于當前項目調(diào)用時傳送兩個參數(shù),item和index。讓我們稱這個函數(shù)為iterator函數(shù)。我們也能象這樣編寫代碼: function myIterator(item, index) { alert('The item in the position #' + index + ' is:' + item); } var myArray = ['first', 'second', 'third']; myArray.each( myIterator ); 我們不會象那些學(xué)校里的那些天真孩子那樣做的,對吧?雖然更嚴格地說,后面的形式更易于理解但導(dǎo)致我們要進入代碼中四處找尋myIterator函數(shù)。最好在它調(diào)用的同一個地方那里有迭代函數(shù)的邏輯。在本案例中,我們也不會在其他任何地方需要迭代函數(shù),所以我們無損地把它轉(zhuǎn)化成一個匿名函數(shù)。 這是this,但有時this也是那個當使用JS開始編寫我們的代碼時,我們最普遍的一個麻煩就是this關(guān)鍵字的使用。它是一個真正的牽絆。 就象我們之前提及的那樣,在JS中一個函數(shù)也是一個對象,而且有時候我們不注意我們正在傳出一個函數(shù)。 拿這小段代碼舉個例: function buttonClicked() { alert('button ' + this.id + ' was clicked'); } var myButton = document.getElementById('someButtonID'); var myButton2 = document.getElementById('someOtherButtonID'); myButton.onclick = buttonClicked; myButton2.onclick = buttonClicked; 由于buttonClicked函數(shù)在任何對象之外被定義,我們也許以為this關(guān)鍵字會包含一個window或document對象(假設(shè)這些代碼位于一個在瀏覽器中被瀏覽的HTML頁面中間)的引用。 但是當我們運行這段代碼時,我們看到它如愿工作并顯示被點擊按鈕的id。究竟其中發(fā)生了什么另我們使每個按鈕的onclick方法包含buttonClicked對象引用,而無論之前那里有什么?,F(xiàn)在無論按鈕什么時候被點擊,瀏覽器都會運行一些類似下行的東西: myButton.onclick(); 那畢竟不是這么混亂,是吧?只要你了解有別的對象要進行處理并想在這些對象的事件上,如點擊按鈕,進行什么行動后發(fā)生了什么就行了。 var myHelper = { formFields: [ ], emptyAllFields: function() { for(i=0; i < this.formFields.length; i++) { var elementID = this.formFields[i]; var field = document.getElementById(elementID); field.value = ''; } } }; //tell which form fields we want to work with myHelper.formFields.push('txtName'); myHelper.formFields.push('txtEmail'); myHelper.formFields.push('txtAddress'); //clearing the text boxes: myHelper.emptyAllFields(); var clearButton = document.getElementById('btnClear'); clearButton.onclick = myHelper.emptyAllFields; 因此你想:好了,現(xiàn)在我可以在我的頁面上點擊Clear按鈕,那三個文本框就將被清空。然后你嘗試點擊該按鈕后僅得到一個運行時錯誤。該錯誤將涉及(猜猜是什么?)this關(guān)鍵字。該問題是this.formFields沒被定義即便this包含了一個到按鈕的引用,那正是現(xiàn)在所發(fā)生的。一個快速的解決方案是重寫我們最后一行的代碼。 clearButton.onclick = function() { myHelper.emptyAllFields(); }; 我們創(chuàng)建一個全新的函數(shù),那種方法在協(xié)助對象的場景中調(diào)用了我們的協(xié)助方法。 |
|