|
原文鏈接:http://www./Articles/333596/What-devs-should-know-about-Javascript
這篇文章中,我將介紹一下javascript最重要的一些關(guān)鍵點(diǎn)。當(dāng)然你學(xué)習(xí)的前提你自己還必須是一個(gè)有經(jīng)驗(yàn)的程序員以及一點(diǎn)點(diǎn)去學(xué)習(xí)js的意愿,而且雖然這篇文章主要是針對(duì)C#以及JAVA開(kāi)發(fā)者來(lái)教學(xué)的,但如果你習(xí)慣了你一樣會(huì)學(xué)到很多有用的東西。 Javascript的語(yǔ)言家族 顧名思義,javascript這個(gè)名稱(chēng)表示它是基于java的,和java差不多的類(lèi)C語(yǔ)言,然而,javascrip并不屬于類(lèi)C語(yǔ)言家族,它實(shí)際上是Java,Scheme,Perl以及它自己的混合衍生物。 膚淺的去看,你應(yīng)該能馬上習(xí)慣javascript,因?yàn)樗恼Z(yǔ)法與java很相像,也有分支結(jié)構(gòu)括號(hào),分號(hào)以及if-for-while-do-switch-throw-catch-finally關(guān)鍵字,我想已經(jīng)適應(yīng)了C#/Java的你肯定會(huì)喜歡。 動(dòng)態(tài)類(lèi)型 與C#/Java的靜態(tài)類(lèi)型語(yǔ)言不同,JS是動(dòng)態(tài)類(lèi)型的,也就是說(shuō)JS變量能夠任意改變它的類(lèi)型,而且你也無(wú)法為方法去定義明確的返回類(lèi)型,如下面的代碼段這是典型的靜態(tài)類(lèi)型語(yǔ)言 int x = 5; x = "hello"; 如果我們馬上編譯代碼的話,顯然會(huì)拋出一個(gè)TypeError的異常。但JS卻不會(huì),哪怕變量的類(lèi)型都改變了。 var x = 5; x = "hello"; 因?yàn)樵贘S中,變量的類(lèi)型本身就是可以改變的,編譯器根本不知道這些變量將代表什么,所以你也別對(duì)JS的編譯器抱太多期望,因?yàn)榫幾g時(shí)檢錯(cuò)有點(diǎn)垃圾以至于你必須更多地在程序運(yùn)行時(shí)進(jìn)行更多的測(cè)試來(lái)找出潛在的BUG。 弱類(lèi)型 JS也是弱類(lèi)型語(yǔ)言,意味著JS可以為變量做任何的隱形類(lèi)型轉(zhuǎn)換,這樣大家可要小心了。在強(qiáng)類(lèi)型語(yǔ)言中,編譯器會(huì)進(jìn)行檢錯(cuò)看能否進(jìn)行轉(zhuǎn)換。比如代碼2+"3"將會(huì)提示錯(cuò)誤。然而在JS將會(huì)直接將數(shù)字轉(zhuǎn)換成字符串,或者bool變量,空數(shù)組轉(zhuǎn)換成數(shù)字,甚至其他什么東西轉(zhuǎn)換成bool變量。。。這一切都是你無(wú)法預(yù)見(jiàn)的。 雖然弱類(lèi)型會(huì)產(chǎn)生很多你無(wú)法預(yù)料的結(jié)果。但依然有兩個(gè)非常重要的關(guān)鍵點(diǎn)我們必須去記?。?/div> 第一,JS有 == 操作符,你也許會(huì)以為這個(gè)與其他語(yǔ)言的 == 操作符一個(gè)意思,但很不幸的是它不是,如果兩個(gè)不同類(lèi)型的變量進(jìn)行 == 操作符比較的話,JS將會(huì)嘗試轉(zhuǎn)換它們的類(lèi)型為一致,然后才進(jìn)行等值判斷。所以請(qǐng)注意下面的代碼,這些代碼在JS中是肯定返回true的。 123 == "123"
true == 1
false == "0"
[] == ""
{} == "[object Object]"不過(guò),幸運(yùn)的是,JS還是有嚴(yán)格的等值判斷操作符的 === 與 !==,如果兩個(gè)變量類(lèi)型不一致的話,=== 是肯定會(huì)返回false的,所以你現(xiàn)在應(yīng)該知道在關(guān)鍵場(chǎng)合你應(yīng)該使用什么等值判斷操作符了吧! 第二,JS將總是將 if 語(yǔ)句的表達(dá)式轉(zhuǎn)換成bool值,以下這些代碼在if判斷語(yǔ)句中將會(huì)被認(rèn)為是false。 false null undefined 0 "" NaN 請(qǐng)記住除此以外,任何其他類(lèi)型的表達(dá)式在JS中都被認(rèn)為是true。 數(shù)據(jù)類(lèi)型 請(qǐng)牢記,JS只包含一種數(shù)據(jù)類(lèi)型,這種數(shù)據(jù)類(lèi)型與你熟悉語(yǔ)言的double幾乎是一樣的,因?yàn)檎麛?shù)如果進(jìn)行除法運(yùn)算的話,可能運(yùn)算結(jié)果會(huì)與你的預(yù)期有出入。同時(shí)也請(qǐng)牢記在JS中的數(shù)據(jù)位移以及位運(yùn)算比較都是很消耗資源的運(yùn)算,因?yàn)檫\(yùn)算前必須先將double轉(zhuǎn)換成整數(shù),運(yùn)算后再將整數(shù)重新轉(zhuǎn)換為double 數(shù)組 在JS中只存在于一種數(shù)組,我們稱(chēng)為arrays,當(dāng)你想使用類(lèi)似其他語(yǔ)言的lists,arrays,vectors,sets或者tuples時(shí),arrays是你唯一的選擇,注意array的容量大小是可動(dòng)態(tài)改變的,而且數(shù)組的每一個(gè)元素也可以是不同的類(lèi)型。 你可以像這樣聲明一個(gè)數(shù)組: var array1 = []; //empty array var array2 = [1, "hello", null, ["bye", 0]]; //array with stuff in it 看上去確實(shí)很簡(jiǎn)單,但我還是要建議你參考 array functions in Javascript 去了解更多關(guān)于JS中的數(shù)組用法。 對(duì)象 因?yàn)閷?duì)象的多變性,對(duì)象在JS中可以說(shuō)是最有特性的元素了,JS里的對(duì)象類(lèi)似一個(gè)關(guān)聯(lián)的字典集合,在左邊你能看到字典的關(guān)鍵詞,與之對(duì)應(yīng)在右邊你能看到該關(guān)鍵詞對(duì)應(yīng)的值,這個(gè)值甚至是其他對(duì)象或者一個(gè)方法。 在JAVA/C#中,你肯定要使用大量的類(lèi),但在JS中,你可以更簡(jiǎn)潔地使用對(duì)象完成同樣的目的。 比如這是一個(gè)Person類(lèi) class Person
{
public string name = "John";
public int age = 25;
public string occupation = "programmer";
}在JS中,你可以使用對(duì)象完成同樣的任務(wù) var person = {
name: "John",
age: 25,
occupation: "programmer"
};但如果你要實(shí)現(xiàn)更加復(fù)雜的類(lèi)呢?比如有構(gòu)造方法,私有字段以及方法的時(shí)候你該怎么做呢? class Person
{
private string name;
private int age;
private string occupation;
public Person(string name, int age, string occupation)
{
this.name = name;
this.age = age;
this.occupation = occupation;
}
public string GetDescription()
{
return name + " is a " + age + " year old person that earns money as a " + occupation + ".";
}
}比如現(xiàn)在你可以實(shí)例化一個(gè)Person然后獲取他的描述 Person John = new Person("John", 25, "programmer");
string biographyOfJohn = John.GetDescription();在JS中沒(méi)有類(lèi)而只有簡(jiǎn)潔的對(duì)象。我們這里看看如何使用對(duì)象來(lái)完成上面的功能: function Person(name, age, occupation) {
return {
name: name,
age: age,
occupation: occupation,
getDescription: function() {
return name + " is a " + age + " year old person that earns money as a " + occupation + ".";
}
};
}現(xiàn)在,你也可以通過(guò)下面的代碼來(lái)初始化一個(gè)Person然后也獲取他的描述了 var John = Person("John", 25, "programmer");
var biographyOfJohn = John.getDescription();方法 JS的方法與C#/JAVA是不一樣的,C#/JAVA的方法是直接屬于類(lèi)的,你可以為某個(gè)方法分配變量,傳遞參數(shù),獲取方法的返回值或者之際將方法作為數(shù)組的元素以及對(duì)象的某個(gè)值。 在JS中,有兩種定義方法的標(biāo)準(zhǔn)語(yǔ)法: function name(arguments) {
//function body
return returnValue;
}或 var name = function(arguments) {
//function body
return returnValue;
}這兩個(gè)不同語(yǔ)法的唯一區(qū)別就是第一個(gè)將自動(dòng)將自己置于程序的全局,這樣你能夠在定義方法的代碼前就能直接調(diào)用該方法 ( Read more about hoisting in Javascript) 而如果你使用第二個(gè)語(yǔ)法規(guī)格的話,你必須在調(diào)用方法前事先定義方法。 范圍 JS只針對(duì)方法才有可使用的范圍限制,顯然這與C#/JAVA的塊區(qū)域是不一樣的,所以如果你寫(xiě)下如下代碼你可能會(huì)碰到一些問(wèn)題 var x = 45;
if(condition) {
var x = 35;
}通過(guò)使用塊,你期望x只是這個(gè)塊的局部變量而不會(huì)影響到外面的同名變量x。但是在JS中,內(nèi)部的x是會(huì)改變外部的同名變量x的。 不過(guò)不用擔(dān)心,代碼質(zhì)量檢測(cè)工具( JSHint)能夠找出這些問(wèn)題并提醒你。 全局變量 請(qǐng)盡量確保你使用'var'關(guān)鍵字來(lái)定義變量,如果不這么做的話,JS將自動(dòng)認(rèn)定這些變量就是全局變量。而這將會(huì)導(dǎo)致很多很難檢測(cè)出來(lái)的BUG。 var globalVar = "global variable";
otherGlobalVar = "other global variable";
function doStuff() {
alsoGlobal = "unfortunately, this is also a global variable";
}上面示例中,所有變量都是定義為全局變量的,globalVar正常, otherGlobalVar就是一個(gè)不好定義方式的典型,而 alsoGlobal這種定義方式顯然是一個(gè)更糟糕的方式,這將導(dǎo)致出無(wú)法預(yù)測(cè)的BUG。再啰嗦一句,請(qǐng)確保使用 JSHint,可以為你省不少事! 文檔對(duì)象模型 DOM(文檔對(duì)象模型)不算是JS獨(dú)有的東西,但對(duì)于JS與網(wǎng)頁(yè)通信是非常重要的,但悲劇的是為了在不同的瀏覽器下正常工作,你可能要做非常煩人的工作,一般情況下我就直接建議你使用DOM抽象框架jQuery. 總結(jié): 我能確信你肯定在開(kāi)發(fā)過(guò)程中會(huì)碰到更多的JS各個(gè)方面的問(wèn)題,但我希望這篇文章能盡量的講述到其中大量的典型問(wèn)題,如果你打算好好研究JS的話,這里有幾個(gè)非常好的站點(diǎn)值得你去取經(jīng):
|
|
|