概述
??JavaScript 是一門充滿爭(zhēng)議的編程語(yǔ)言:它以 Java 命名,但實(shí)際上和 Java 毫無關(guān)系鸟廓。JavaScript 的創(chuàng)造 只用了 10 天時(shí)間,但在 20 年時(shí)間里卻發(fā)展成世界上最流行的 Web 開發(fā)語(yǔ)言。如果為 JavaScript 今日的地位和流行程度找一個(gè)原因座咆,那毫無疑問是容易上手的語(yǔ)言特性徽惋。當(dāng)然案淋,精通 JavaScript 是一項(xiàng)艱巨的任務(wù),但學(xué)會(huì)足夠開發(fā) Web 應(yīng)用和游戲的知識(shí)卻很簡(jiǎn)單险绘,如果你已經(jīng)有了一定編程基礎(chǔ)踢京,熟悉 JavaScript 語(yǔ)言特性不會(huì)花費(fèi)你多長(zhǎng)時(shí)間誉碴。
??另外,在使用 Cocos Creator 開發(fā)游戲時(shí)你大多數(shù)情況下都會(huì)重復(fù)使用一些固有的模式瓣距。根據(jù)帕雷托法則(也叫二八定律)黔帕,掌握一門語(yǔ)言的 20% 就足夠你應(yīng)付 80% 以上的情況了。現(xiàn)在就讓我們來花最短的時(shí)間學(xué)習(xí)足夠的 JavaScript 知識(shí)蹈丸,以便我們開始使用 Cocos Creator 開發(fā)游戲成黄。
邊讀邊嘗試
??如果你能看到這篇文章,那么你已經(jīng)具備了全功能的 JavaScript 開發(fā)環(huán)境 —— 我說的就是你正在使用的瀏覽器逻杖!
??在本頁(yè)面中讀到的所有例子奋岁,你都可以把它們輸入到瀏覽器的控制臺(tái)里并查看運(yùn)行結(jié)果,如果你不清楚怎么做弧腥,可以閱讀文檔 如何在不同瀏覽器中打開控制臺(tái)的指南厦取。
變量
??在 JavaScript 中,我們像這樣聲明一個(gè)變量:
var a;
??保留字 var
之后緊跟著的管搪,就是一個(gè)變量名虾攻,接下來我們可以為變量賦值:
var a = 12;
??在閱讀其他人的 JavaScript 代碼時(shí),你也會(huì)看到下面這樣的變量聲明:
a = 12;
??如果你在瀏覽器控制臺(tái)中嘗試更鲁,會(huì)發(fā)現(xiàn) JavaScript 在面對(duì)省略 var
時(shí)的變量聲明并不會(huì)報(bào)錯(cuò)霎箍,但在 Cocos Creator 項(xiàng)目腳本中,聲明變量時(shí)的 var
是不能省略的澡为,否則編譯器會(huì)報(bào)錯(cuò)漂坏。
函數(shù)
??在 JavaScript 里我們像這樣聲明函數(shù):
var myAwesomeFunction = function (myArgument) {
}
??像這樣調(diào)用函數(shù):
myAwesomeFunction(something);
??我們看到函數(shù)聲明也和變量聲明一樣遵從 var something = somethingElse
的模式。因?yàn)樵?JavaScript 里媒至,函數(shù)和變量本質(zhì)上是一樣的顶别,我們可以像下面這樣把一個(gè)函數(shù)當(dāng)做參數(shù)傳入另一個(gè)函數(shù)中:
square = function (a) {
return a * a;
}
applyOperation = function (f, a) {
return f(a);
}
applyOperation (square, 10);
返回值
??函數(shù)的返回值是由 return
打頭的語(yǔ)句定義的,我們這里要了解的是函數(shù)體內(nèi) return
語(yǔ)句之后的內(nèi)容是不會(huì)被執(zhí)行的拒啰。
myFunction = function (a) {
return a * 3;
explodeComputer();
}
If
??JavaScript 中條件判斷語(yǔ)句 if
是這樣用的:
if (foo) {
return bar;
}
If / else
??if
后的值如果為 false驯绎,會(huì)執(zhí)行 else
中的語(yǔ)句:
if (foo) {
function1();
}
else {
function2();
}
??if
/ else
條件判斷還可以像這樣寫成一行:
foo ? function1() : function2();
??當(dāng) foo
的值為 true 時(shí),表達(dá)式會(huì)返回 function1()
的執(zhí)行結(jié)果谋旦,反之會(huì)返回 function2()
的執(zhí)行結(jié)果剩失。當(dāng)我們需要根據(jù)條件來為變量賦值時(shí),這種寫法就非常方便:
var n = foo ? 1 : 2;
??上面的語(yǔ)句可以表述為:當(dāng) foo
是 true 時(shí)册着,將 n
的值賦為 1拴孤,否則賦為 2。當(dāng)然我們還可以使用 else if
來處理更多的判斷類型:
if (foo) {
function1();
}
else if (bar) {
function2();
}
else {
function3();
}
JavaScript 數(shù)組(Array)
??JavaScript 里像這樣聲明數(shù)組:
a = [123, 456, 789];
??像這樣訪問數(shù)組中的成員:(從 0 開始索引)
a[1];
JavaScript 對(duì)象(Object)
??我們像這樣聲明一個(gè)對(duì)象(object):
myProfile = {
name: "Jare Guo",
email: "blabla@gmail.com",
'zip code': 12345,
isInvited: true
}
??在對(duì)象聲明的語(yǔ)法(myProfile = {...}
)之中甲捏,有一組用逗號(hào)相隔的鍵值對(duì)演熟。每一對(duì)都包括一個(gè) key(字符串類型,有時(shí)候會(huì)用雙引號(hào)包裹)和一個(gè) value(可以是任何類型:包括 string司顿,number绽媒,boolean蚕冬,變量名,數(shù)組是辕,對(duì)象甚至是函數(shù))。我們管這樣的一對(duì)鍵值叫做對(duì)象的屬性(property)猎提,key 是屬性名获三,value 是屬性值。你可以在 value 中嵌套其他對(duì)象锨苏,或者由一組對(duì)象組成的數(shù)組:
myProfile = {
name: "Jare Guo",
email: "blabla@gmail.com",
city: "Xiamen",
points: 1234,
isInvited: true,
friends: [
{
name: "Johnny",
email: "blablabla@gmail.com"
},
{
name: "Nantas",
email: "piapiapia@gmail.com"
}
]
}
??訪問對(duì)象的某個(gè)屬性非常簡(jiǎn)單疙教,我們只要使用 dot 語(yǔ)法就可以了,還可以和數(shù)組成員的訪問結(jié)合起來:
myProfile.name;
myProfile.friends[1].name;
??JavaScript 中的對(duì)象無處不在伞租,在函數(shù)的參數(shù)傳遞中也會(huì)大量使用贞谓,比如在 Cocos Creator 中,我們就可以像這樣定義 FireClass 對(duì)象:
var MyComponent = cc.Class({
extends: cc.Component
});
??{extends: cc.Component}
這就是一個(gè)用做函數(shù)參數(shù)的對(duì)象葵诈。在 JavaScript 中大多數(shù)情況我們使用對(duì)象時(shí)都不一定要為他命名裸弦,很可能會(huì)像這樣直接使用。
匿名函數(shù)
??我們之前試過了用變量聲明的語(yǔ)法來定義函數(shù):
myFunction = function (myArgument) {
}
??再?gòu)?fù)習(xí)一下將函數(shù)作為參數(shù)傳入其他函數(shù)調(diào)用中的用法:
square = function (a) {
return a * a;
}
applyOperation = function (f, a) {
return f(a);
}
applyOperation(square, 10);
??我們還見識(shí)了 JavaScript 的語(yǔ)法是多么喜歡偷懶作喘,所以我們就可以用這樣的方式代替上面的多個(gè)函數(shù)聲明:
applyOperation = function (f, a) {
return f(a);
}
applyOperation(
function(a){
return a*a;
},
)
??我們這次并沒有聲明 square
函數(shù)理疙,并將 square
作為參數(shù)傳遞,而是在參數(shù)的位置直接寫了一個(gè)新的函數(shù)體泞坦,這樣的做法被稱為匿名函數(shù)窖贤,在 JavaScript 中是最為廣泛使用的模式。
鏈?zhǔn)秸Z(yǔ)法
??下面我們介紹一種在數(shù)組和字符串操作中常用的語(yǔ)法:
var myArray = [123, 456];
myArray.push(789)
var myString = "abcdef";
myString.replace("a", "z");
??上面代碼中的點(diǎn)符號(hào)表示 “調(diào)用 myString
字符串對(duì)象的 replace
函數(shù)贰锁,并且傳遞 a
和 z
作為參數(shù)赃梧,然后獲得返回值。
??使用點(diǎn)符號(hào)的表達(dá)式豌熄,最大的優(yōu)點(diǎn)是你可以把多項(xiàng)任務(wù)鏈接在一個(gè)表達(dá)式里授嘀,當(dāng)然前提是每個(gè)調(diào)用的函數(shù)必須有合適的返回值。我們不會(huì)過多介紹如何定義可鏈接的函數(shù)房轿,但是使用它們是非常簡(jiǎn)單的粤攒,只要使用以下的模式:something.function1().function2().function3()
鏈條中的每個(gè)環(huán)節(jié)都會(huì)接到一個(gè)初始值,調(diào)用一個(gè)函數(shù)囱持,然后把函數(shù)執(zhí)行結(jié)果傳遞到下一環(huán)節(jié):
var n = 5;
n.double().square();
This
??this
可能是 JavaScript 中最難以理解和掌握的概念了夯接。
??簡(jiǎn)單地說,this
關(guān)鍵字能讓你訪問正在處理的對(duì)象:就像變色龍一樣纷妆,this
也會(huì)隨著執(zhí)行環(huán)境的變化而變化盔几。
??解釋 this
的原理是很復(fù)雜的,不妨讓我們使用兩種工具來幫助我們?cè)趯?shí)踐中理解 this
的值:
??首先是最普通又最常用的 console.log()
掩幢,它能夠?qū)?duì)象的信息輸出到瀏覽器的控制臺(tái)里逊拍。在每個(gè)函數(shù)體開始的地方加入一個(gè) console.log()
上鞠,確保我們了解當(dāng)時(shí)運(yùn)行環(huán)境下正在處理的對(duì)象是什么。
myFunction = function (a, b) {
console.log(this);
}
??另外一個(gè)方法是將 this
賦值給另外一個(gè)變量:
myFunction = function (a, b) {
var myObject = this;
}
??乍一看好像這樣子并沒有什么作用芯丧,實(shí)際上它允許你安全的使用 myObject
這個(gè)變量來指代最初執(zhí)行函數(shù)的對(duì)象芍阎,而不用擔(dān)心在后面的代碼中 this
會(huì)變成其他東西。關(guān)于 JavaScript 里 this
的詳細(xì)原理說明缨恒,請(qǐng)參考這篇文章 this 的值到底是什么谴咸?一次說清楚。
運(yùn)算符
??=
是賦值運(yùn)算符骗露,a = 12
表示把 “12” 賦值給變量 a
岭佳。
??如果你需要比較兩個(gè)值,可以使用 ==
萧锉,例如 a == 12
珊随。
??JavaScript 中還有個(gè)獨(dú)特的 ===
運(yùn)算符,它能夠比較兩邊的值和類型是否全都相同柿隙。(類型是指 string, number 這些):
a = "12";
a == 12;
a === 12;
??大多數(shù)情況下叶洞,我們都推薦使用 ===
運(yùn)算符來比較兩個(gè)值,因?yàn)橄M容^兩個(gè)不同類型但有著相同值的情況是比較少見的优俘。
??下面是 JavaScript 判斷兩個(gè)值是否不相等的比較運(yùn)算符:
a = 12;
a !== 11;
??!
運(yùn)算符還可以單獨(dú)使用京办,用來對(duì)一個(gè) boolean 值取反:
a = true;
!a;
??!
運(yùn)算符總會(huì)得到一個(gè) boolean 類型的值,所以可以用來將非 boolean 類型的值轉(zhuǎn)為 boolean 類型:
a = 12;
!a;
!!a;
或者:
a = 0;
!a;
!!a;
代碼風(fēng)格
??最后帆焕,下面這些代碼風(fēng)格上的規(guī)則能幫助我們寫出更清晰明確的代碼:
- 使用駝峰命名法:定義
myRandomVariable
這樣的變量名惭婿,而不是my_random_variable
- 在每一行結(jié)束時(shí)寫一個(gè)
;
,盡管在 JavaScript 里行尾的;
是可以忽略的 - 在每個(gè)關(guān)鍵字前后都加上空格叶雹,如
a = b + 1
财饥,而不是a = b + 1