JavaScript是客戶端和服務器端腳本語言,可以插入到HTML頁面中,并且是目前較熱門的Web開發語言。同時,JavaScript也是面向對象編程語言。
類似的基本題目還包括:JavaScript都有哪些類型?JavaScript是誰發明的?...
Java是一門十分完整、成熟的編程語言。相比之下,JavaScript 是一個可以被引入HTML頁面的編程語言。這兩種語言并不完全相互依賴,而是針對不同的意圖而設計的。Java是一種面向對象編程(OOPS)或結構化編程語言,類似的如C ++或C,而JavaScript是客戶端腳本語言,它被稱為非結構化編程。
JavaScript更快。JavaScript是一種客戶端語言,因此它不需要Web服務器的協助來執行。另一方面,ASP是服務器端語言,因此總是比JavaScript慢。值得注意的是,Javascript現在也可用于服務器端語言(nodejs)。
負無窮大是JavaScript中的一個數字,可以通過將負數除以零來得到。
在字符串語句中可以通過在第一行末尾使用反斜杠“”來完成。
例:document.write("This is a program")
如果不是在字符串語句中更改為新行,那么javaScript會忽略行中的斷點。
例:var x=1, y=2, z=x+y
上面的代碼是完美的,但并不建議這樣做,因為阻礙了調試。
未聲明的變量是程序中不存在且未聲明的變量。如果程序嘗試讀取未聲明變量的值,則會遇到運行時錯誤。
未定義的變量是在程序中聲明但尚未給出任何值的變量。如果程序嘗試讀取未定義變量的值,則返回未定義的值。
全局變量是整個代碼長度可用的變量,也就是說這些變量沒有任何作用域。var關鍵字用于聲明局部變量或對象。如果省略var關鍵字,則聲明一個全局變量。
例:// Declare a global globalVariable=“Test”
使用全局變量所面臨的問題是本地和全局變量名稱的沖突。此外,很難調試和測試依賴于 全局變量的代碼。
定時器用于在設定的時間執行一段代碼,或者在給定的時間間隔內重復該代碼。這通過使用函數setTimeout,setInterval和clearInterval來完成。
setTimeout(function,delay)函數用于啟動在所述延遲之后調用特定功能的定時器。
setInterval(function,delay)函數用于在提到的延遲中重復執行給定的功能,只有在取消時才停止。
clearInterval(id)函數指示定時器停止。
定時器在一個線程內運行,因此事件可能需要排隊等待執行。
“ViewState”特定于會話中的頁面。
“SessionState”特定于可在Web應用程序中的所有頁面上訪問的用戶特定數據。
===被稱為嚴格等式運算符,當兩個操作數具有相同的值而沒有任何類型轉換時,該運算符返回true。
for、while、do-while loops
parseInt() 函數解析一個字符串參數,并返回一個指定基數的整數。parseInt()將要轉換的字符串作為其第一個參數,第二個參數是給定字符串的基礎。為了將4F(基數16)轉換為整數,所使用的代碼是:parseInt("4F", 16)
“==”僅檢查值相等,而“===”是一個更嚴格的等式判定,如果兩個變量的值或類型不同,則返回false。
由于3和2是整數,它們將直接相加。由于7是一個字符串,它將會被直接連接,所以結果將是57。
為了檢測客戶端機器上的操作系統,應使用avigator.appVersion 字符串(屬性)。
NULL用于表示無值或無對象。它意味著沒有對象或空字符串,沒有有效的布爾值,沒有 數值和數組對象。
delete操作符用于刪除程序中的所有變量或對象,但不能刪除使用 VAR關鍵字聲明的變量。
Alert、Confirm and Prompt
Void(0)用于防止頁面刷新,并在調用時傳遞參數“zero”。 Void(0)用于調用另一種方法而不刷新頁面。
必須插入以下代碼才能達到預期效果:
使用特殊字符(如單引號,雙引號,撇號和&符號)時,將使用轉義字符(反斜杠)。在字符前放置反斜杠,使其顯示。
例:
Cookie是用來存儲計算機中的小型測試文件,當用戶訪問網站以存儲他們需要的信息時,它將被創建。
pop()方法與shift()方法類似,但不同之處在于Shift方法在數組的開頭工作。此外,pop()方法將最后一個元素從給定的數組中取出并返回。然后改變被調用的數組。
例:
var cloths=[“Shirt”, “Pant”, “TShirt”];
cloths.pop();
//Now cloth becomes Shirt,Pant
如果在JavaScript中使用innerHTML,缺點是:
1)內容隨處可見;
2)不能像“追加到innerHTML”一樣使用;
3)即使你使用+=like“innerHTML=innerHTML +'html'”舊 的內容仍然會被html替換;
4)整個innerHTML內容被重新解析并構建成元素,因此它的速度要慢得多;
5)innerHTML不提供驗證,因此我們可能會在文檔中插入有效的和破壞性的HTML并將其中斷。
break語句從當前循環中退出。
continue語句繼續下一個循環語句。
Primitive
Reference types
原始類型是數字和布爾數據類型。引用類型是更復雜的類型,如字符串和日期。
通用對象可以創建為:
var I=new object();
"Typeof"是一個運算符,用于返回變量類型的字符串描述。
try... Catch-finally用于處理JavaScript中的異常。
有三種類型的錯誤:
Load time errors:該錯誤發生于加載網頁時,例如出現語法錯誤等狀況,稱為加載時間 錯誤,并且會動態生成錯誤。
Run time errors:由于在HTML 語言中濫用命令而導致的錯誤。
Logical Errors:這是由于在具有不同操作的函數上執行了錯誤邏輯而發生的錯誤。
push方法用于將一個或多個元素添加或附加到數組的末尾。使用這種方法,可以通過傳遞多個參數來附加多個元素。
Unshift方法就像在數組開頭工作的push方法。該方法用于將一個或多個元素添加到數組的開頭。
屬性按以下方式分配給對象:
obj["class"]=12或obj.class=12
在載入頁面的所有信息之前,不運行onload函數。這導致在執行任何代碼之前會出現延遲。
onDocumentReady在加載DOM之后加載代碼。這允許早期的代碼操縱。
Closure是與函數返回時保留在內存中的函數相關的本地聲明變量。
可以以給定的方式將值附加到數組:
arr[arr.length]=value
for-in循環用于循環對象的屬性。
for-in循環的語法是:
在每次循環中,來自對象的一個屬性與變量名相關聯,循環繼續,直到對象的所有屬性都 被耗盡。
被聲明為沒有任何命名標識符的函數被稱為匿名函數。一般來說,匿名函數在聲明后無法訪問。
匿名函數聲明:
函數.call()和.apply()在使用上非常相似,只是有一點區別。當程序員知道函數參數的編號時,使用.call(),因為它們必須在調用語句中被提及為參數。另一方面,當不知道數字時使用.apply(),函數.apply()期望參數為數組。.call()和.apply()之間的基本區別在于將參數傳遞給函數。它們的用法可以通過給定的例子進行說明。
JavaScript允許DOM元素嵌套在一起。在這種情況下,如果單擊子級的處理程序,父級的處理程序也將執行同樣的工作。
“And”運算符(&&),'Or'運算符(||)和'Not'運算符(!)可以在JavaScript中使用。
*運算符沒有括號。
web-garden和web-farm都是網絡托管系統。唯一的區別是web-garden是在單個服務器中包含許多處理器的設置,而web-farm是使用多個服務器的較大設置。
將屬性分配給對象的方式與賦值給變量值相同。例如,表單對象的操作值以下列方式分配為“submit”:Document.form.action=“submit”
可以通過使用JavaScript擴展(從JavaScript編輯器運行),打開文件的示例來完成:
fh=fopen(getScriptPath(), 0)
DOM代表文檔對象模型,并且負責文檔中各種對象的相互交互。DOM是開發網頁所必需的,其中包括諸如段落,鏈接等對象。可以操作這些對象以包括添加或刪除等操作,DOM還需要向網頁添加額外的功能。除此之外,API的使用比其他更有優勢。
事件是由用戶生成活動(例如單擊鏈接或填寫表單)導致的操作。需要一個事件處理程序來管理所有這些事件的正確執行。事件處理程序是對象的額外屬性。此屬性包括事件的名稱以及事件發生時采取的操作。
默認情況下,在頁面加載期間,HTML代碼的解析將暫停,直到腳本停止執行。這意味著,如果服務器速度較慢或者腳本特別沉重,則會導致網頁延遲。在使用Deferred時,腳本會延遲執行直到HTML解析器運行。這減少了網頁加載時間,并且它們的顯示速度更快。
JavaScript中的不同功能組件是:
First-class函數:JavaScript中的函數被用作第一類對象。這通常意味著這些函數可以作為參數傳遞給其他函數,作為其他函數的值返回,分配給變量,也可以存儲在數據結構中。
嵌套函數:在其他函數中定義的函數稱為嵌套函數。
該方法在數組啟動時起作用,與push()不同。它將所需數量的元素添加到數組的頂部。
例如:
輸出如下所示:[“joseph”,“Jane”, “charlie”, “john”]
EncodeURl()用于將URL轉換為十六進制編碼。而DecodeURI()用于將編碼的URL轉換回正常。
innerHTML內容每次刷新,因此很慢。在innerHTML中沒有驗證的余地,因此,更容易在文檔中插入錯誤代碼,從而使網頁不穩定。
在<script>標簽之后的代碼中添加“<! - ”,不帶引號。
在<script>標簽之前添加“// - >”代碼中沒有引號。
舊瀏覽器現在將JavaScript代碼視為一個長的HTML注釋。而支持JavaScript的瀏覽器則將“<! - ”和“// - >”作為一行注釋。
Object、number、function、boolean、underfind
強制(parseInt,parseFloat,number)
隱式(==–===)
前者是切割成數組的形式,后者是將數組轉換成字符串。
普通添加事件的方法不支持添加多個事件,最下面的事件會覆蓋上面的,而事件綁定(addEventListener)方式添加事件可以添加多個。
1)執行順序不一樣
2)參數不一樣
3)事件加不加on
4)this指向問題
Var ev=ev || window.event; document.documentElement.clientWidth || document.body.clientWidth;
Var target=ev.srcElement||ev.target
一個在url后面,一個放在虛擬載體里面
有大小限制
安全問題
應用不同:一個是論壇等只需要請求的,一個是類似修改密碼的
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
使用eval parse,鑒于安全性考慮使用parse更靠譜。
讓利用事件冒泡的原理,讓自己的所觸發的事件,讓他的父元素代替執行!
例子可見此鏈接:http://www.webasily.com/?p=78
閉包就是能夠讀取其他函數內部變量的函數。
此鏈接可查看:http://blog.csdn.net/gaoshanw...
canceBubble、return、false
obj.appendChidl()
obj.innersetBefore
obj.replaceChild
obj.removeChild
動態創建script標簽,回調函數
Ajax是頁面無刷新請求數據操作
本地對象為array obj regexp等可以new實例化
內置對象為gload Math等不可以實例化的
宿主對象為瀏覽器自帶的document,window等
Document.onload是在結構和樣式加載完才執行js; Document.ready原生種沒有這個方法,jquery中有 $().ready(function)
前者會自動轉換類型,后者不會。
一段腳本只能讀取來自于同一來源的窗口和文檔的屬性,這里的同一來源指的是主機名、協議和端口號的組合。
載說明:原創不易,未經授權,謝絕任何形式的轉載
層疊樣式表(CSS)是一種強大的樣式表語言,可以幫助前端開發人員為簡單的網頁添加樣式。然而,在使用這種樣式表語言時,開發人員可能會犯一些錯誤。這些錯誤會妨礙開發人員編寫高效的代碼。本文探討了一些常見的錯誤,并為每個錯誤提供了解決方案。
以下是我們開發人員經常犯的九個最常見的錯誤;你也犯過其中一些嗎?
!important 是 CSS 中的一個關鍵字,它可以幫助我們將屬性值設置為比其他樣式選項更重要。例如,如果您將 !important 聲明應用于元素樣式,那么該樣式將覆蓋該屬性類別的所有其他樣式。以下是語法:
selector {
property: value !important;
}
例如,如果您有一個標題元素 - h1 ,就像這樣:
<h1 class="css-mistake">CSS Mistakes</h1>
然后您應用以下樣式規則:
h1 {
color: red;
}
.css-mistake {
color: green;
}
默認情況下,標題文本的顏色將為“綠色”,因為類選擇器具有比元素(標簽)選擇器更高的CSS特異性選擇器。但是使用 !important ,您可以覆蓋該樣式CSS規則(從而使元素(標簽)選擇器覆蓋類選擇器)。通過這種方式,標題文本的顏色將為紅色,優先于類選擇器設置的綠色。
h1 {
color: red !important;
}
過度使用 !important 會導致特異性戰爭-一種狀態,其中樣式開始互相覆蓋,無法按照樣式表的作者定義的方式工作。下一節將通過列舉適當使用 !important 的實例來提供解決此問題的方法。
什么時候應該使用?
就像本節標題所說的那樣——“過度使用 !important ”,我們在使用這個關鍵詞時必須小心謹慎。只有在迫切需要時才應該節制地使用 !important 。以下是一些使用它的情況:
在進行樣式設計時,使用正確的長度單位對于創建響應式設計至關重要。CSS有兩類長度單位:絕對單位和相對單位。許多CSS屬性,如“寬度”、“高度”、“字體大小”等,都使用單位來表示其值。下面的代碼片段給出了單位的使用示例:
selector {
font-size: 14px;
}
在上面的代碼片段中,我們聲明了“font-size”CSS屬性,然后給它賦了一個14px的值。
什么是絕對單位?
這些是長度單位,無論渲染媒體如何,都具有固定的值,與設備的屏幕尺寸無關。這些單位非常適合在不同屏幕尺寸上保持元素的相同大小。你可能已經使用過一些標準的絕對單位,如像素 - px, 點 - pt, 英寸 - in, 毫米 - mm, 厘米 - cm, 和派卡 - pc. 絕對單位為我們提供了準確、固定和精確的樣式值,但它們不會根據屏幕尺寸進行縮放。絕對單位不適用于實現響應式設計。因此,將它們限制在不需要根據瀏覽器尺寸或設備屏幕尺寸進行調整的元素上。另一方面,相對單位如其名稱所示,是相對于另一個屬性(大多數情況下是父元素)的。這些單位具有靈活性,可以根據視口動態增長,適應響應式設計,與絕對單位不同。一些相對單位的例子是百分比(%)- rem, em, 等等。
如何使用相對單位及其解釋
了解每個相關單位的重要性,使您具備有效使用它們的知識。以下是一些相關單位及其解釋:
% - 這個單位完全依賴于父元素。因此,它是相對于父元素的。例如,如果你將一個元素的寬度設置為80%,它將是父元素寬度的80%。請注意,在以下屬性的值中使用百分比:寬度、高度、邊距和內邊距。
em - 這與父元素的字體大小相關。例如,如果您將元素的字體大小設置為4em,則它將是父元素字體大小的四倍。在處理排版(文本)時使用 em - 這使文本按比例縮放。
rem - 這是相對于根元素的字體大小。通常使用 rem 來實現整個布局的一致樣式。
vh - 相對于視口高度的1%。
vw - 相對于視口寬度的1%。
內聯樣式是一種通過 style 屬性將直接樣式傳遞給HTML元素的樣式系統。雖然存在這種樣式系統,但重要的是要理解它的使用不支持應用程序構建的最佳實踐,因為它會創建不可重用的代碼。只有在測試或美化簡單的HTML文件時才使用內聯樣式。以下是一些避免使用這種樣式系統的原因:
最佳實踐
為了克服內聯樣式的缺點,您必須使用內部樣式表(位于 <style> 標簽內的樣式)或外部樣式表來保持您的代碼健康和有組織。
不同的瀏覽器具有各種默認樣式,這些樣式不同,導致元素的外觀不一致。這就是為什么我們必須定義一些樣式,以便在其他瀏覽器上為網頁樣式提供一致的起點。這些樣式被稱為“CSS重置”。CSS重置是一種CSS樣式,用于刪除瀏覽器默認樣式的規則。如果您熟悉CSS,并且在使用過程中有時會注意到某些特定屬性的默認樣式,如 margin. ,CSS重置可以幫助我們將樣式基礎調整到一致的水平。以下是使用這些重置的原因:
如何創建自己的CSS重置
這里是要遵循的簡單步驟:
* {
margin: 0;
padding: 0;
border: 0;
}
上面的代碼是一個基本的CSS重置,它針對邊距、內邊距和邊框屬性,將每個屬性的值設為0。這個過程被稱為“標準化過程”,它可以消除瀏覽器默認的間距和邊框。這里有一些在線的CSS重置:
CSS中的單行代碼是CSS代碼的速記樣式。它可以使代碼更加清晰和有結構。掌握這些速記技巧將有助于您編寫更簡潔的代碼(將多行代碼壓縮為單行)。例如,當您想要在所有邊緣(上,下,左,右)處對元素邊距進行樣式設置時,您不需要明確地指定所有屬性(如 margin-top, margin-right, margin-bottom, 和 margin-left, ),您可以直接使用邊距屬性的速記方式。下面的代碼解釋了這一點:
/* Don't do this */
margin-top: 10px;
margin-bottom: 10px;
margin-right: 15px;
margin-left: 15px;
/* Instead, use Margin Shorthand */
margin: 10px 20px 10px 20px;
/* Margin Shorthand can even be more simplified */
margin: 10px 20px;
這些簡短的話語帶來了許多優點:
CSS選擇器可以在外部或內部樣式表中定位HTML元素。CSS中有許多選擇器方法,包括標簽(元素)、類、ID和偽元素。知道何時使用選擇器以及何時不使用選擇器非常重要。此外,您還必須了解CSS選擇器的工作原理。
如何避免使用過于復雜的選擇器
如果你在你的樣式表中遇到了像下面這樣的代碼片段,那就意味著你正在使用過于復雜的選擇器。
#container > .box > content .section .title p > span .italic {
color: blue;
font-weight: bold;
}
以下是避免過于復雜選擇器的技巧:
瀏覽器兼容性很重要,因為你不希望樣式在一個瀏覽器上良好運行,在另一個瀏覽器上則運行不正常。忽略瀏覽器兼容性可能會導致用戶在不同瀏覽器上的體驗不一致。這是因為不同的瀏覽器有其自己的CSS樣式渲染方式。但是,你可以通過考慮瀏覽器兼容性并確保你的樣式與不同瀏覽器兼容來實現樣式一致性。實現瀏覽器兼容性代碼的一種方法是實施以下操作:
使用供應商前綴:某些CSS屬性需要您使用前綴來渲染,無論使用哪種瀏覽器。需要這些前綴的瀏覽器包括Internet Explorer,Mozilla Firefox和Safari。這些前綴被稱為供應商前綴,因為它們是特定類型的瀏覽器獨有的。前綴的示例: -webkit-, -moz-, 和 -ms-. 。
/* webkit-prefixed version - used by browsers that use the WebKit layout engine, such as Chrome and Safari- */
-webkit-border-radius: 8px;
/* ms-prefixed version -used by browsers that use the Microsoft layout engine, such as Internet Explorer. */
-ms-border-radius: 10px;
/* standard version */
border-radius: 8px;
聲明字體回退:在為“font-family”等屬性分配值時,您必須添加回退字體。如果自定義字體不可用,回退字體將是實施的選項之一。
利用Can I Use網站檢查CSS屬性在各種瀏覽器中的兼容性。(https://caniuse.com/)
Hex碼是顏色的十六進制表示。它是一個由“#”符號前綴的6位代碼,后跟三對十六進制數字,其中第一對表示紅色值,第二對表示綠色值,最后一對表示藍色值。語法:
使用直接的顏色關鍵詞有一些限制:
顏色名稱在不同的瀏覽器中是不一致的。例如,如果你將顏色屬性設置為綠色,不同的瀏覽器對其解釋的方式也會有所不同。因此,不同瀏覽器之間的渲染是不一致的。
顏色名稱受到限制,因為您無法調整它們的色調、陰影等。
顏色名稱的選擇有限。由于使用顏色名稱的限制,我們需要選擇使用十六進制代碼,這些代碼沒有這些限制。以下是十六進制代碼比顏色關鍵字更合適的原因:
尋找十六進制代碼的高效方法
以下是獲取十六進制代碼的幾種方法:
使用0px替代0:毫無疑問,這可能不會對樣式表產生影響,但為了最佳實踐,請確保使用0而不是0px。
selector {
/*Don't do this*/
padding: 10px 12px 15px 0px;
/*Do this*/
padding: 10px 12px 15px 0;
}
設置高的z-index值:給 z-index 分配高值是非常不必要和過度的。遲早,這將在你的樣式表中造成問題,特別是當 z-index. 有多個實現時。
selector {
/*Don't do this*/
z-index: 50;
/*Do this*/
z-index: 2; /*Let the value be minimal*/
}
本文深入探討了常見的CSS錯誤,并為每個錯誤提供了深入的解決方案。通過閱讀本指南,毫無疑問您已經了解了一些常見的CSS錯誤,并且從此以后,您將知道如何解決它們,因為我們還要研究每個錯誤的解決方案。
由于文章內容篇幅有限,今天的內容就分享到這里,文章結尾,我想提醒您,文章的創作不易,如果您喜歡我的分享,請別忘了點贊和轉發,讓更多有需要的人看到。同時,如果您想獲取更多前端技術的知識,歡迎關注我,您的支持將是我分享最大的動力。我會持續輸出更多內容,敬請期待。
avaScript 因為互聯網而生,緊隨著瀏覽器的出現而問世。
今天我們一起來學習一個新的系列教程,【JavaScript 標準參考教程】,今天開始它的第一篇章,【基本語法篇】
1、語句
JavaScript 程序的執行單位為行(line),也就是一行一行地執行。一般情況下,每一行就是一個語句。
語句(statement)是為了完成某種任務而進行的操作,比如下面就是一行賦值語句。
var a=1 + 3;
這條語句先用var命令,聲明了變量a,然后將1 + 3的運算結果賦值給變量a。
1 + 3叫做表達式(expression),指一個為了得到返回值的計算式。語句和表達式的區別在于,前者主要為了進行某種操作,一般情況下不需要返回值;后者則是為了得到返回值,一定會返回一個值。凡是 JavaScript 語言中預期為值的地方,都可以使用表達式。比如,賦值語句的等號右邊,預期是一個值,因此可以放置各種表達式。
語句以分號結尾,一個分號就表示一個語句結束。多個語句可以寫在一行內。
var a=1 + 3 ; var b='abc';
分號前面可以沒有任何內容,JavaScript引擎將其視為空語句。
;;;
上面的代碼就表示3個空語句。
表達式不需要分號結尾。一旦在表達式后面添加分號,則 JavaScript 引擎就將表達式視為語句,這樣會產生一些沒有任何意義的語句。
1 + 3;'abc';
上面兩行語句只是單純地產生一個值,并沒有任何實際的意義。
2、變量
2.1、概念
變量是對“值”的具名引用。變量就是為“值”起名,然后引用這個名字,就等同于引用這個值。變量的名字就是變量名。
var a=1;
上面的代碼先聲明變量a,然后在變量a與數值1之間建立引用關系,稱為將數值1“賦值”給變量a。以后,引用變量名a就會得到數值1。最前面的var,是變量聲明命令。它表示通知解釋引擎,要創建一個變量a。
注意,JavaScript 的變量名區分大小寫,A和a是兩個不同的變量。
變量的聲明和賦值,是分開的兩個步驟,上面的代碼將它們合在了一起,實際的步驟是下面這樣。
var a; a=1;
如果只是聲明變量而沒有賦值,則該變量的值是undefined。undefined是一個 JavaScript 關鍵字,表示“無定義”。
var a; a // undefined
如果變量賦值的時候,忘了寫var命令,這條語句也是有效的。
var a=1; // 基本等同 a=1;
但是,不寫var的做法,不利于表達意圖,而且容易不知不覺地創建全局變量,所以建議總是使用var命令聲明變量。
如果一個變量沒有聲明就直接使用,JavaScript 會報錯,告訴你變量未定義。
x// ReferenceError: x is not defined
上面代碼直接使用變量x,系統就報錯,告訴你變量x沒有聲明。
可以在同一條var命令中聲明多個變量。
var a, b;
JavaScript 是一種動態類型語言,也就是說,變量的類型沒有限制,變量可以隨時更改類型。
var a=1; a='hello';
上面代碼中,變量a起先被賦值為一個數值,后來又被重新賦值為一個字符串。第二次賦值的時候,因為變量a已經存在,所以不需要使用var命令。
如果使用var重新聲明一個已經存在的變量,是無效的。
var x=1; var x; x // 1
上面代碼中,變量x聲明了兩次,第二次聲明是無效的。
但是,如果第二次聲明的時候還進行了賦值,則會覆蓋掉前面的值。
var x=1; var x=2; // 等同于 var x=1; var x; x=2;
2.2、變量提升
JavaScript 引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,然后再一行一行地運行。這造成的結果,就是所有的變量的聲明語句,都會被提升到代碼的頭部,這就叫做變量提升(hoisting)。
console.log(a); var a=1;
上面代碼首先使用console.log方法,在控制臺(console)顯示變量a的值。這時變量a還沒有聲明和賦值,所以這是一種錯誤的做法,但是實際上不會報錯。因為存在變量提升,真正運行的是下面的代碼。
var a; console.log(a); a=1;
最后的結果是顯示undefined,表示變量a已聲明,但還未賦值。
3、標識符
標識符(identifier)指的是用來識別各種值的合法名稱。最常見的標識符就是變量名,以及后面要提到的函數名。JavaScript 語言的標識符對大小寫敏感,所以a和A是兩個不同的標識符。
標識符有一套命名規則,不符合規則的就是非法標識符。JavaScript 引擎遇到非法標識符,就會報錯。
簡單說,標識符命名規則如下。
?第一個字符,可以是任意 Unicode 字母(包括英文字母和其他語言的字母),以及美元符號($)和下劃線(_)。
?第二個字符及后面的字符,除了 Unicode 字母、美元符號和下劃線,還可以用數字0-9。
下面這些都是合法的標識符。
arg0 _tmp $elem π
下面這些則是不合法的標識符。
1a // 第一個字符不能是數字 23 // 同上 *** // 標識符不能包含星號 a+b // 標識符不能包含加號 -d // 標識符不能包含減號或連詞線
中文是合法的標識符,可以用作變量名。
var 臨時變量=1;
JavaScript有一些保留字,不能用作標識符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。
4、注釋
源碼中被 JavaScript 引擎忽略的部分就叫做注釋,它的作用是對代碼進行解釋。Javascript 提供兩種注釋的寫法:一種是單行注釋,用//起頭;另一種是多行注釋,放在/*和*/之間。
// 這是單行注釋/* 這是 多行 注釋 */
此外,由于歷史上 JavaScript 可以兼容 HTML 代碼的注釋,所以<!--和-->也被視為合法的單行注釋。
x=1; <!-- x=2; --> x=3;
上面代碼中,只有x=1會執行,其他的部分都被注釋掉了。
需要注意的是,-->只有在行首,才會被當成單行注釋,否則會當作正常的運算。
function countdown(n){ while (n --> 0) console.log(n);}countdown(3 // 2 // 1 // 0
上面代碼中,n --> 0實際上會當作n-- > 0,因此輸出2、1、0。
5、區塊
JavaScript 使用大括號,將多個相關的語句組合在一起,稱為“區塊”(block)。
對于var命令來說,JavaScript 的區塊不構成單獨的作用域(scope)。
{ var a=1; }a // 1
上面代碼在區塊內部,使用var命令聲明并賦值了變量a,然后在區塊外部,變量a依然有效,區塊對于var命令不構成單獨的作用域,與不使用區塊的情況沒有任何區別。在 JavaScript 語言中,單獨使用區塊并不常見,區塊往往用來構成其他更復雜的語法結構,比如for、if、while、function等。
6、條件語句
JavaScript 提供if結構和switch結構,完成條件判斷,即只有滿足預設的條件,才會執行相應的語句。
6.1、if 結構
if結構先判斷一個表達式的布爾值,然后根據布爾值的真偽,執行不同的語句。所謂布爾值,指的是 JavaScript 的兩個特殊值,true表示真,false表示偽。
if (布爾值) 語句; // 或者 if (布爾值) 語句;
上面是if結構的基本形式。需要注意的是,“布爾值”往往由一個條件表達式產生的,必須放在圓括號中,表示對表達式求值。如果表達式的求值結果為true,就執行緊跟在后面的語句;如果結果為false,則跳過緊跟在后面的語句。
if (m===3) m=m + 1;
上面代碼表示,只有在m等于3時,才會將其值加上1。
這種寫法要求條件表達式后面只能有一個語句。如果想執行多個語句,必須在if的條件判斷之后,加上大括號,表示代碼塊(多個語句合并成一個語句)。
if (m===3) { m +=1; }
建議總是在if語句中使用大括號,因為這樣方便插入語句。
注意,if后面的表達式之中,不要混淆賦值表達式(=)、嚴格相等運算符(===)和相等運算符(==)。尤其是賦值表達式不具有比較作用。
var x=1; var y=2; if (x=y) { console.log(x); } // "2"
上面代碼的原意是,當x等于y的時候,才執行相關語句。但是,不小心將嚴格相等運算符寫成賦值表達式,結果變成了將y賦值給變量x,再判斷變量x的值(等于2)的布爾值(結果為true)。
這種錯誤可以正常生成一個布爾值,因而不會報錯。為了避免這種情況,有些開發者習慣將常量寫在運算符的左邊,這樣的話,一旦不小心將相等運算符寫成賦值運算符,就會報錯,因為常量不能被賦值。
if (x=2) { // 不報錯 if (2=x) { // 報錯
至于為什么優先采用“嚴格相等運算符”(===),而不是“相等運算符”(==),請參考《運算符》章節。
6.2、if…else 結構
if代碼塊后面,還可以跟一個else代碼塊,表示不滿足條件時,所要執行的代碼。
if (m===3) { // 滿足條件時,執行的語句 } else { // 不滿足條件時,執行的語句 }
上面代碼判斷變量m是否等于3,如果等于就執行if代碼塊,否則執行else代碼塊。
對同一個變量進行多次判斷時,多個if...else語句可以連寫在一起。
if (m===0) { // ...} else if (m===1) { // ...} else if (m===2) { // ...} else { // ...}
else代碼塊總是與離自己最近的那個if語句配對。
var m=1; var n=2; if (m !==1) if (n===2) console.log('hello'); else console.log('world');
上面代碼不會有任何輸出,else代碼塊不會得到執行,因為它跟著的是最近的那個if語句,相當于下面這樣。
if (m !==1) { if (n===2) { console.log('hello'); } else { console.log('world'); }}
如果想讓else代碼塊跟隨最上面的那個if語句,就要改變大括號的位置。
if (m !==1) { if (n===2) { console.log('hello'); }} else { console.log('world');} // world
6.3、switch結構
多個if...else連在一起使用的時候,可以轉為使用更方便的switch結構。
switch (fruit) { case "banana": // ... break; case "apple": // ... break; default: // ...}
上面代碼根據變量fruit的值,選擇執行相應的case。如果所有case都不符合,則執行最后的default部分。需要注意的是,每個case代碼塊內部的break語句不能少,否則會接下去執行下一個case代碼塊,而不是跳出switch結構。
var x=1;switch (x) { case 1: console.log('x 等于1'); case 2: console.log('x 等于2'); default: console.log('x 等于其他值');} // x等于1 // x等于2 // x等于其他值
上面代碼中,case代碼塊之中沒有break語句,導致不會跳出switch結構,而會一直執行下去。正確的寫法是像下面這樣。
switch (x) { case 1: console.log('x 等于1'); break; case 2: console.log('x 等于2'); break; default: console.log('x 等于其他值');}
switch語句部分和case語句部分,都可以使用表達式。
switch(1 + 3) { case 2 + 2: f(); break; default: neverHappens();}
上面代碼的default部分,是永遠不會執行到的。
需要注意的是,switch語句后面的表達式,與case語句后面的表示式比較運行結果時,采用的是嚴格相等運算符(===),而不是相等運算符(==),這意味著比較時不會發生類型轉換。
var x=1;switch (x) { case true: console.log('x 發生類型轉換'); default: console.log('x 沒有發生類型轉換');} // x 沒有發生類型轉換
上面代碼中,由于變量x沒有發生類型轉換,所以不會執行case true的情況。這表明,switch語句內部采用的是“嚴格相等運算符”,詳細解釋請參考《運算符》一節。
6.4、三元運算符 ?:
JavaScript還有一個三元運算符(即該運算符需要三個運算子)?:,也可以用于邏輯判斷。
(條件) ? 表達式1 : 表達式2
上面代碼中,如果“條件”為true,則返回“表達式1”的值,否則返回“表達式2”的值。
var even=(n % 2===0) ? true : false;
上面代碼中,如果n可以被2整除,則even等于true,否則等于false。它等同于下面的形式。
var even;if (n % 2===0) { even=true; } else { even=false; }
這個三元運算符可以被視為if...else...的簡寫形式,因此可以用于多種場合。
var myVar;console.log( myVar ? 'myVar has a value' : 'myVar do not has a value' ) // myVar do not has a value
上面代碼利用三元運算符,輸出相應的提示。
var msg='數字' + n + '是' + (n % 2===0 ? '偶數' : '奇數');
上面代碼利用三元運算符,在字符串之中插入不同的值。
7、循環語句
循環語句用于重復執行某個操作,它有多種形式。
7.1、while 循環
While語句包括一個循環條件和一段代碼塊,只要條件為真,就不斷循環執行代碼塊。
while (條件) 語句;// 或者 while (條件) 語句;
while語句的循環條件是一個表達式,必須放在圓括號中。代碼塊部分,如果只有一條語句,可以省略大括號,否則就必須加上大括號。
while (條件) { 語句; }
下面是while語句的一個例子。
var i=0;while (i < 100) { console.log('i 當前為:' + i); i=i + 1; }
上面的代碼將循環100次,直到i等于100為止。
下面的例子是一個無限循環,因為循環條件總是為真。
while (true) { console.log('Hello, world'); }
7.2、for 循環
for語句是循環命令的另一種形式,可以指定循環的起點、終點和終止條件。它的格式如下。
for (初始化表達式; 條件; 遞增表達式) 語句 // 或者 for (初始化表達式; 條件; 遞增表達式) { 語句 }
for語句后面的括號里面,有三個表達式。
?初始化表達式(initialize):確定循環變量的初始值,只在循環開始時執行一次。
?條件表達式(test):每輪循環開始時,都要執行這個條件表達式,只有值為真,才繼續進行循環。
?遞增表達式(increment):每輪循環的最后一個操作,通常用來遞增循環變量。
下面是一個例子。
var x=3;for (var i=0; i < x; i++) { console.log(i); } // 0 // 1 // 2
上面代碼中,初始化表達式是var i=0,即初始化一個變量i;測試表達式是i < x,即只要i小于x,就會執行循環;遞增表達式是i++,即每次循環結束后,i增大1。
所有for循環,都可以改寫成while循環。上面的例子改為while循環,代碼如下。
var x=3; var i=0; while (i < x) { console.log(i); i++; }
for語句的三個部分(initialize、test、increment),可以省略任何一個,也可以全部省略。
for ( ; ; ){ console.log('Hello World'); }
上面代碼省略了for語句表達式的三個部分,結果就導致了一個無限循環。
7.3、do…while 循環
do...while循環與while循環類似,唯一的區別就是先運行一次循環體,然后判斷循環條件。
do 語句while (條件); // 或者 do { 語句 } while (條件);
不管條件是否為真,do...while循環至少運行一次,這是這種結構最大的特點。另外,while語句后面的分號注意不要省略。
下面是一個例子。
var x=3;] var i=0; do { console.log(i); i++; } while(i < x);
7.4、break 語句和 continue 語句
break語句和continue語句都具有跳轉作用,可以讓代碼不按既有的順序執行。
break語句用于跳出代碼塊或循環。
var i=0; while(i < 100) { console.log('i 當前為:' + i); i++; if (i===10) break;}
上面代碼只會執行10次循環,一旦i等于10,就會跳出循環。
for循環也可以使用break語句跳出循環。
for (var i=0; i < 5; i++) { console.log(i); if (i===3) break; } // 0 // 1 // 2 // 3
上面代碼執行到i等于3,就會跳出循環。
continue語句用于立即終止本輪循環,返回循環結構的頭部,開始下一輪循環。
var i=0; while (i < 100){ i++; if (i % 2===0) continue; console.log('i 當前為:' + i); }
上面代碼只有在i為奇數時,才會輸出i的值。如果i為偶數,則直接進入下一輪循環。
如果存在多重循環,不帶參數的break語句和continue語句都只針對最內層循環。
7.5、標簽(label)
JavaScript 語言允許,語句的前面有標簽(label),相當于定位符,用于跳轉到程序的任意位置,標簽的格式如下。
label: 語句
標簽可以是任意的標識符,但不能是保留字,語句部分可以是任意語句。
標簽通常與break語句和continue語句配合使用,跳出特定的循環。
top: for (var i=0; i < 3; i++){ for (var j=0; j < 3; j++){ if (i===1 && j===1) break top; console.log('i=' + i + ', j=' + j); } } // i=0, j=0 // i=0, j=1 // i=0, j=2 // i=1, j=0
上面代碼為一個雙重循環區塊,break命令后面加上了top標簽(注意,top不用加引號),滿足條件時,直接跳出雙層循環。如果break語句后面不使用標簽,則只能跳出內層循環,進入下一次的外層循環。
continue語句也可以與標簽配合使用。
top: for (var i=0; i < 3; i++){ for (var j=0; j < 3; j++){ if (i===1 && j===1) continue top; console.log('i=' + i + ', j=' + j); } } // i=0, j=0 // i=0, j=1 // i=0, j=2 // i=1, j=0 // i=2, j=0 // i=2, j=1 // i=2, j=2
上面代碼中,continue命令后面有一個標簽名,滿足條件時,會跳過當前循環,直接進入下一輪外層循環。如果continue語句后面不使用標簽,則只能進入下一輪的內層循環。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。