【JavaScript從入門到放棄】JS基礎(chǔ)-01
作為一個前端開發(fā)人員,JS是我們行走江湖吃飯的家伙?;旧弦粋€前端人員能值多少大洋,就看JS了。雖然各種框架層出不窮,但是歸根結(jié)底學(xué)好原生JS才是硬道理。
學(xué)習(xí)任何新東西其實都遵循 10000 小時成才定律,只要付出時間,就會有收獲。人與人的不同只是收獲的多少不同。關(guān)于天賦問題,我們確實要承認(rèn)某些人在某些領(lǐng)域確實比其他人厲害。但大部分人其實都是普通人,不需要天賦,只需要通過時間的簡單堆積就可以混口飯吃。
彈鋼琴能到郎朗那個級別的人是少數(shù)了,多數(shù)藝術(shù)生都普普通通,畢業(yè)出來混個鋼琴老師當(dāng)當(dāng),辦個培訓(xùn)學(xué)校賺點錢娶媳婦兒生孩子,最多寫本書什么的。只有投入足夠多的時間,你發(fā)現(xiàn)某些人確實比你厲害,這個時候才適合討論天賦問題。所以,不要自我否定,才是真正的成長的開始。
咱們言歸正傳吧。
一,JavaScript的組成
JavaScript主要由以下3部分組成:
ECMAScript:解釋器、翻譯
DOM:Document Object Model(文檔對象模型)
BOM:Browser Object Model(瀏覽器對象模型)
ECMAScript類似于翻譯的角色,將編寫好的可讀性高的代碼翻譯成計算機(jī)可以識別的二進(jìn)制代碼,并將計算機(jī)反饋回來的信息翻譯給我們。ECMAScript是JS的核心,通常稱為:解釋器。
ECMAScript為JS提供了最基本的功能,但這些功能是十分有限的,如何能讓JS具有編寫網(wǎng)頁代碼的能力呢?此時我們就要用到DOM了。DOM中的Document(文檔)其實就是HTML文檔,并且DOM還賦予了JS操作HTML的能力。在JS里DOM是以document的形式展現(xiàn)的。
BOM使得JS擁有了操作瀏覽器的能力,在JavaScript當(dāng)中BOM以window的形式存在,有了BOM,JS就擁有了類似彈窗,關(guān)閉窗口,復(fù)制內(nèi)容到剪貼板等與瀏覽器相關(guān)的功能。
從兼容性的角度來看的話,ES(ECMAScript)基本上不存在兼容性問題,DOM有一些操作上的不兼容,而BOM完全不兼容,所以盡可能避免使用BOM,這樣可以省去很多的麻煩。
二,變量類型
首先說變量,從字面上理解就是可以變化的量,放到編程語言里面,就是可以被賦值改變的量。和變量對應(yīng)的就是常量,我們經(jīng)常遇到的比如,10,20這樣的不能改變的數(shù)字,就是常量,一個確定的值。不能被賦值也不能被改變。
在JS中我們把變量分為了多種類型。
var a = 1024;
alert(typeof a);
var a = 'cos';
alert(typeof a);
var a = true;
alert(typeof a);
var a = function (){ alert('cos'); }
alert(typeof a);
var a = document;
alert(typeof a);
typeof 是一個一元運算,放在一個運算數(shù)之前,運算數(shù)可以是任意類型。它返回值是一個字符串,該字符串說明運算數(shù)的類型。
我們可以通過typeof返回變量類型,那么上面的例子的輸出結(jié)果,依次為:number(數(shù)值),string(字符串),boolean(布爾),function(函數(shù)),object(對象)。在這5中基礎(chǔ)數(shù)據(jù)類型之外,JS還存在一種叫undefined的類型,一般存在于如下兩種情況:
alert(typeof b);
變量b沒有進(jìn)行過定義,所以JS返回的數(shù)值類型為undefined(未定義的)。
var b;
alert(typeof b);
這時,雖然我們定義了變量b,但在JS里,變量的類型只取決于變量內(nèi)存的值,而變量b內(nèi)沒有值,因此它的數(shù)據(jù)類型依然是undefined。
JS沒有限制變量的數(shù)據(jù)類型,顯得更加靈活,但如果一個變量不停地更改類型,會顯得非常的混亂。所以同一個變量,最好只存放一種類型的數(shù)據(jù)。
三,變量類型的轉(zhuǎn)換
變量不僅有類型,而且可以進(jìn)行類型之間的轉(zhuǎn)換。如果某個數(shù)據(jù)的類型不符合我們的需求,那么就需要用到數(shù)據(jù)類型的轉(zhuǎn)換。我們一起舉個‘栗子’:
在網(wǎng)頁中添加兩個文本框和一個按鈕,并希望點擊按鈕后文本框中的數(shù)字可以相加。這個功能看起來很簡單,如果直接寫的話,因為textbox中value的屬性是以字符串形式返回給JS的,這就導(dǎo)致輸入的兩個數(shù)字最后會被當(dāng)做字符串相加而不是數(shù)值。這時候,我們就需要將字符串轉(zhuǎn)換為數(shù)字。
將字符串轉(zhuǎn)化為數(shù)字的方法為parseInt()。
這是關(guān)于parseInt()的一個例子:
var a = '1024'; alert(parseInt(a)+1);
這里我們將a定義為了字符串,但是通過parseInt轉(zhuǎn)化后得到了數(shù)值類型的數(shù)據(jù),所以輸出結(jié)果為1025。需要注意的是,parseInt是從左到右依次掃描字符串,一旦發(fā)現(xiàn)不是數(shù)字的字符,就立即停止工作,并將前面的字符通過數(shù)值類型返回,所以下面三種情況的返回結(jié)果依次為1024,1024,NaN:
var a = '1024px'; var b = '1024px24'; var c = 'abc'; alert(parseInt(a)); alert(parseInt(b)); alert(parseInt(c));
這里的 NaN 是Not a Number的簡寫,簡言之就是JS解析不出數(shù)字時會返回這個結(jié)果。
所以,我們這個案例可以通過如下代碼完成:
<script> window.onload=function () { var oTxt1=document.getElementById('txt1'); var oTxt2=document.getElementById('txt2'); var oBtn=document.getElementById('btn1');
oBtn.onclick=function () { alert(parseInt(oTxt1.value)+parseInt(oTxt2.value)); }; }; </script> <body> <input id="txt1" type="text" /> <input id="txt2" type="text" /> <input id="btn1" type="button" value="求和" /> </body>
運行結(jié)果:

這里有一個問題,我們并沒有對文本框進(jìn)行任何限制,當(dāng)用戶向文本框輸入的是字母而不是數(shù)字的時候,程序是不能正常執(zhí)行的。所以,這時候需要判斷一下對文本框輸入值通過 parseInt 方法轉(zhuǎn)換出來的結(jié)果是不是 NaN,如果是NaN,就說明用戶輸入某個值或者這兩個值不是數(shù)字,此時需要返回給用戶一個提示。
那么問題來了,在JS里,NaN十分的奇葩:
var a=parseInt('abc');
var b=parseInt('def');
alert(a==b);
此時,a和b的值都是NaN,但這個程序的執(zhí)行結(jié)果居然是false,這告訴我們在JS里NaN和NaN是不相等的。換言之,判斷結(jié)果是不是NaN,不能通過==進(jìn)行比較。好在天無絕人之路,JS提供了一個函數(shù):isNaN(),用于檢測一個變量是否為NaN。
現(xiàn)在我們來看:
輸入字母的時候效果如下:
通過 if 進(jìn)行判斷,如果用戶有輸入的不是數(shù)字,則彈出與之對應(yīng)的錯誤提示框;如果輸入的兩個值都沒有錯誤,將會彈出正確答案。
那么使用parseInt轉(zhuǎn)換小數(shù),會怎么樣呢?
var a='3.5';
alert(parseInt(a));
輸出結(jié)果為3。對于parseInt而言,轉(zhuǎn)換出來的數(shù)字如果是小數(shù),就會舍去小數(shù)部分,只保留整數(shù)部分。
如果我們需要用到小數(shù)的話,請使用parseInt的兄弟——parseFloat,這兩者在使用方法上沒有任何區(qū)別,你照貓畫虎的試試看。當(dāng)你不知道轉(zhuǎn)換出來的數(shù)值是整數(shù)還是小數(shù)的時候,請優(yōu)先選擇使用parseFloat,此時即便轉(zhuǎn)換前的變量為整數(shù)也不會出現(xiàn)數(shù)值缺損。
在我們剛才所講的類型轉(zhuǎn)換中,明確地告知了計算機(jī)我們想要對數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換,我們將這種方法稱為顯式類型轉(zhuǎn)換(也可以理解為:強制轉(zhuǎn)換)。同樣,還有一種轉(zhuǎn)換類型的方式被我們稱為隱式類型轉(zhuǎn)換。隱式類型轉(zhuǎn)換最簡單的例子如下:
var a=5;
var b='5';
alert(a==b);
理論上來講的話,二者數(shù)據(jù)類型不相同,輸出結(jié)果應(yīng)該為flase。但是瀏覽器給出的答案是true。請和下面的例子做一個對比:
var a=5;
var b='5';
alert(a===b);
此時,返回的答案變成了false。那么問題來了,==和===二者之間存在什么區(qū)別呢?
對于==運算符來說,它在比較之前會先把二者的數(shù)據(jù)類型轉(zhuǎn)換為一致;而 === 運算符(全等運算符)不轉(zhuǎn)換類型,直接比較。在不轉(zhuǎn)換類型的情況下,a和b肯定是不相等。由此可知,在比較a==b時,并沒有明確告知計算機(jī)我們想要對a或b的類型進(jìn)行轉(zhuǎn)換,但是計算機(jī)自己卻偷偷進(jìn)行了轉(zhuǎn)換,這就是我們所講的隱式類型轉(zhuǎn)換。除開該例子之外,還存在另一種隱式轉(zhuǎn)換的情況:
var a='12';
var b='5';
alert(a-b);
如果這里是a+b,計算機(jī)就會默認(rèn)是字符串相加(拼接)而彈出125。但是如果是a-b的話,計算機(jī)會在做減法之前進(jìn)行隱式轉(zhuǎn)換成數(shù)值類型,我們就得到答案7。
為什么加法不會進(jìn)行隱式轉(zhuǎn)換而減法會?因為在JS中+運算符本身具備字符串拼接和數(shù)字相加這兩個功能,如果+識別為字符串拼接,一步即可完成計算,直接拼接即可;但是如果識別為數(shù)字相加,就需要兩步才可以完成計算,即:先轉(zhuǎn)換類型,再相加。對于計算機(jī)而言,一定會選擇步驟更少的路徑,所以說加法不會進(jìn)行隱式轉(zhuǎn)換。而在JS中,-運算符只有數(shù)字相減的功能,此時JS不得不進(jìn)行隱式轉(zhuǎn)換。
四,變量作用域
變量作用域指的是變量可以起作用的范圍。
function aaa(){
var a=12;
}
function bbb(){
alert(a);
}
aaa();
bbb();
運行這個程序,在bbb函數(shù)內(nèi)會出現(xiàn)變量a沒有被定義的報錯。事實上,a確實沒有被定義,因為在aaa中定義的a是局部變量,而局部變量,只能在定義它的函數(shù)里面使用。和局部變量相對的一個概念是全局變量。
var a;
function aaa(){
a=12;
}
function bbb(){
alert(a);
}
aaa();
bbb();
這個例題當(dāng)中的a被聲明在所有函數(shù)的外面,這樣的變量是全局變量,可以在任何地方使用,所以能夠正常彈出12。
五,閉包
關(guān)于閉包的概念,我建議你現(xiàn)階段先不用深究,如果很感興趣的話可以Google一下。咱們說過,局部變量只能在定義它的函數(shù)內(nèi)使用。那么,有一種情況例外:
function aaa(){
var a=12;
function bbb()
{
alert(a);
}
bbb();
}
aaa();
當(dāng)函數(shù)bbb被包含在函數(shù)aaa內(nèi)時,程序可以成功運行。此種寫法就被稱為閉包。閉包有很多高級的應(yīng)用,當(dāng)然這些都是后話,我們慢慢學(xué)習(xí)。在閉包結(jié)構(gòu)中,aaa稱為父函數(shù),bbb稱為子函數(shù)。對于閉包而言,子函數(shù)可以使用父函數(shù)的局部變量。事實上,剛剛我們已經(jīng)使用過閉包了,例如上面的求和函數(shù)。
六,命名規(guī)范
命名規(guī)范,即怎樣給函數(shù)以及變量取名字。
給函數(shù)和變量取名字和給你孩子取名字差不多,理論而言是可以隨便取的,但實際應(yīng)用中又不能顯得太俗太low,否則可能會引起隔壁老王的不滿。
關(guān)于命名規(guī)范:
可讀性——容易看懂
規(guī)范性——合乎規(guī)則
可讀性代表取名盡可能讓人能看懂。要是代碼通篇都是aaa,bbb,ccc這樣的取名,又正好碰到程序比較龐大,此時閱讀將是一件非常痛苦的事情。
規(guī)范性表示JS有一個較為約定俗稱的命名規(guī)則,大部分情況下采用匈牙利命名法或者類似方法,其原則為:
類型前綴
首字母大寫
JS中常見類型前綴:

類型前綴一般表明了變量存儲的類型,使我們一眼就能辨識變量當(dāng)中存的是什么,其他人拿到代碼的時候就不會胡亂更改數(shù)據(jù)類型,這樣保證了代碼的規(guī)范和更好的可讀性。一般而言只有變量遵循前綴的規(guī)范,而函數(shù)則沒有這個必要。
當(dāng)一個變量或者函數(shù)名由多個英文單詞組成的時候,我們通常使用駝峰法命名,每個單詞的首字母使用大寫,例如oBtnUserLogin,這種命名方式可以更清晰地判斷變量的含義。

浙公網(wǎng)安備 33010602011771號