W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
JavaScript程序的執(zhí)行單位為行(line),也就是一行一行地執(zhí)行。一般情況下,每一行就是一個(gè)語(yǔ)句。
語(yǔ)句(statement)是為了完成某種任務(wù)而進(jìn)行的操作,比如下面就是一行賦值語(yǔ)句:
var a = 1 + 3;
這條語(yǔ)句先用var
命令,聲明了變量a
,然后將1 + 3
的運(yùn)算結(jié)果賦值給變量a
。
1 + 3
叫做表達(dá)式(expression),指一個(gè)為了得到返回值的計(jì)算式。語(yǔ)句和表達(dá)式的區(qū)別在于,前者主要為了進(jìn)行某種操作,一般情況下不需要返回值;后者則是為了得到返回值,一定會(huì)返回一個(gè)值。
凡是JavaScript語(yǔ)言中預(yù)期為值的地方,都可以使用表達(dá)式。比如,賦值語(yǔ)句的等號(hào)右邊,預(yù)期是一個(gè)值,因此可以放置各種表達(dá)式。一條語(yǔ)句可以包含多個(gè)表達(dá)式。
語(yǔ)句以分號(hào)結(jié)尾,一個(gè)分號(hào)就表示一個(gè)語(yǔ)句結(jié)束。多個(gè)語(yǔ)句可以寫(xiě)在一行內(nèi)。
var a = 1 + 3 ; var b = 'abc';
分號(hào)前面可以沒(méi)有任何內(nèi)容,JavaScript引擎將其視為空語(yǔ)句。
;;;
上面的代碼就表示3個(gè)空語(yǔ)句。(關(guān)于分號(hào)的更多介紹,請(qǐng)看后文《代碼風(fēng)格》一節(jié)。)
表達(dá)式不需要分號(hào)結(jié)尾。一旦在表達(dá)式后面添加分號(hào),則JavaScript引擎就將表達(dá)式視為語(yǔ)句,這樣會(huì)產(chǎn)生一些沒(méi)有任何意義的語(yǔ)句。
1 + 3;
'abc';
上面兩行語(yǔ)句有返回值,但是沒(méi)有任何意義,因?yàn)橹皇欠祷匾粋€(gè)單純的值,沒(méi)有任何其他操作。
變量是對(duì)“值”的引用,使用變量等同于引用一個(gè)值。每一個(gè)變量都有一個(gè)變量名。
var a = 1;
上面的代碼先聲明變量a
,然后在變量a
與數(shù)值1之間建立引用關(guān)系,也稱(chēng)為將數(shù)值1“賦值”給變量a
。以后,引用變量a
就會(huì)得到數(shù)值1。最前面的var
,是變量聲明命令。它表示通知解釋引擎,要?jiǎng)?chuàng)建一個(gè)變量a
。
變量的聲明和賦值,是分開(kāi)的兩個(gè)步驟,上面的代碼將它們合在了一起,實(shí)際的步驟是下面這樣。
var a;
a = 1;
如果只是聲明變量而沒(méi)有賦值,則該變量的值是undefined
。undefined
是一個(gè)JavaScript關(guān)鍵字,表示“無(wú)定義”。
var a;
a // undefined
如果變量賦值的時(shí)候,忘了寫(xiě)var
命令,這條語(yǔ)句也是有效的。
var a = 1;
// 基本等同
a = 1;
但是,不寫(xiě)var
的做法,不利于表達(dá)意圖,而且容易不知不覺(jué)地創(chuàng)建全局變量,所以建議總是使用var
命令聲明變量。
嚴(yán)格地說(shuō),
var a = 1
與a = 1
,這兩條語(yǔ)句的效果不完全一樣,主要體現(xiàn)在delete
命令無(wú)法刪除前者。不過(guò),絕大多數(shù)情況下,這種差異是可以忽略的。
如果一個(gè)變量沒(méi)有聲明就直接使用,JavaScript會(huì)報(bào)錯(cuò),告訴你變量未定義。
x
// ReferenceError: x is not defined
上面代碼直接使用變量x
,系統(tǒng)就報(bào)錯(cuò),告訴你變量x
沒(méi)有聲明。
可以在同一條var
命令中聲明多個(gè)變量。
var a, b;
JavaScript 是一種動(dòng)態(tài)類(lèi)型語(yǔ)言,也就是說(shuō),變量的類(lèi)型沒(méi)有限制,可以賦予各種類(lèi)型的值。
var a = 1;
a = 'hello';
上面代碼中,變量a
起先被賦值為一個(gè)數(shù)值,后來(lái)又被重新賦值為一個(gè)字符串。第二次賦值的時(shí)候,因?yàn)樽兞?code class="highlighter-rouge">a已經(jīng)存在,所以不需要使用var
命令。
如果使用var
重新聲明一個(gè)已經(jīng)存在的變量,是無(wú)效的。
var x = 1;
var x;
x // 1
上面代碼中,變量x
聲明了兩次,第二次聲明是無(wú)效的。
但是,如果第二次聲明的同時(shí)還賦值了,則會(huì)覆蓋掉前面的值。
var x = 1;
var x = 2;
// 等同于
var x = 1;
var x;
x = 2;
JavaScript引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,然后再一行一行地運(yùn)行。這造成的結(jié)果,就是所有的變量的聲明語(yǔ)句,都會(huì)被提升到代碼的頭部,這就叫做變量提升(hoisting)。
console.log(a);
var a = 1;
上面代碼首先使用console.log
方法,在控制臺(tái)(console)顯示變量a的值。這時(shí)變量a
還沒(méi)有聲明和賦值,所以這是一種錯(cuò)誤的做法,但是實(shí)際上不會(huì)報(bào)錯(cuò)。因?yàn)榇嬖谧兞刻嵘嬲\(yùn)行的是下面的代碼。
var a;
console.log(a);
a = 1;
最后的結(jié)果是顯示undefined
,表示變量a
已聲明,但還未賦值。
請(qǐng)注意,變量提升只對(duì)var
命令聲明的變量有效,如果一個(gè)變量不是用var
命令聲明的,就不會(huì)發(fā)生變量提升。
console.log(b);
b = 1;
上面的語(yǔ)句將會(huì)報(bào)錯(cuò),提示“ReferenceError: b is not defined”,即變量b
未聲明,這是因?yàn)?code class="highlighter-rouge">b不是用var
命令聲明的,JavaScript引擎不會(huì)將其提升,而只是視為對(duì)頂層對(duì)象的b
屬性的賦值。
標(biāo)識(shí)符(identifier)是用來(lái)識(shí)別具體對(duì)象的一個(gè)名稱(chēng)。最常見(jiàn)的標(biāo)識(shí)符就是變量名,以及后面要提到的函數(shù)名。JavaScript語(yǔ)言的標(biāo)識(shí)符對(duì)大小寫(xiě)敏感,所以a
和A
是兩個(gè)不同的標(biāo)識(shí)符。
標(biāo)識(shí)符有一套命名規(guī)則,不符合規(guī)則的就是非法標(biāo)識(shí)符。JavaScript引擎遇到非法標(biāo)識(shí)符,就會(huì)報(bào)錯(cuò)。
簡(jiǎn)單說(shuō),標(biāo)識(shí)符命名規(guī)則如下:
$
)和下劃線(_
)。0-9
。下面這些都是合法的標(biāo)識(shí)符。
arg0
_tmp
$elem
π
下面這些則是不合法的標(biāo)識(shí)符。
1a // 第一個(gè)字符不能是數(shù)字
23 // 同上
*** // 標(biāo)識(shí)符不能包含星號(hào)
a+b // 標(biāo)識(shí)符不能包含加號(hào)
-d // 標(biāo)識(shí)符不能包含減號(hào)或連詞線
中文是合法的標(biāo)識(shí)符,可以用作變量名。
var 臨時(shí)變量 = 1;
JavaScript有一些保留字,不能用作標(biāo)識(shí)符: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。
另外,還有三個(gè)詞雖然不是保留字,但是因?yàn)榫哂刑貏e含義,也不應(yīng)該用作標(biāo)識(shí)符:Infinity
、NaN
、undefined
。
源碼中被JavaScript引擎忽略的部分就叫做注釋?zhuān)淖饔檬菍?duì)代碼進(jìn)行解釋。Javascript提供兩種注釋?zhuān)阂环N是單行注釋?zhuān)?/起頭;另一種是多行注釋?zhuān)旁?* 和 */之間。
// 這是單行注釋
/*
這是
多行
注釋
*/
此外,由于歷史上JavaScript兼容HTML代碼的注釋?zhuān)?code class="highlighter-rouge"><!--和-->
也被視為單行注釋。
x = 1; <!-- x = 2;
--> x = 3;
上面代碼中,只有x = 1
會(huì)執(zhí)行,其他的部分都被注釋掉了。
需要注意的是,-->
只有在行首,才會(huì)被當(dāng)成單行注釋?zhuān)駝t就是一個(gè)運(yùn)算符。
function countdown(n) {
while (n --> 0) console.log(n);
}
countdown(3)
// 2
// 1
// 0
上面代碼中,n --> 0
實(shí)際上會(huì)當(dāng)作n-- > 0
,因此輸出2、1、0。
JavaScript使用大括號(hào),將多個(gè)相關(guān)的語(yǔ)句組合在一起,稱(chēng)為“區(qū)塊”(block)。
與大多數(shù)編程語(yǔ)言不一樣,JavaScript的區(qū)塊不構(gòu)成單獨(dú)的作用域(scope)。也就是說(shuō),區(qū)塊中的變量與區(qū)塊外的變量,屬于同一個(gè)作用域。
{
var a = 1;
}
a // 1
上面代碼在區(qū)塊內(nèi)部,聲明并賦值了變量a
,然后在區(qū)塊外部,變量a
依然有效,這說(shuō)明區(qū)塊不構(gòu)成單獨(dú)的作用域,與不使用區(qū)塊的情況沒(méi)有任何區(qū)別。所以,單獨(dú)使用的區(qū)塊在JavaScript中意義不大,很少出現(xiàn)。區(qū)塊往往用來(lái)構(gòu)成其他更復(fù)雜的語(yǔ)法結(jié)構(gòu),比如for
、if
、while
、function
等。
條件語(yǔ)句提供一種語(yǔ)法構(gòu)造,只有滿(mǎn)足某個(gè)條件,才會(huì)執(zhí)行相應(yīng)的語(yǔ)句。JavaScript提供if
結(jié)構(gòu)和switch
結(jié)構(gòu),完成條件判斷。
if
結(jié)構(gòu)先判斷一個(gè)表達(dá)式的布爾值,然后根據(jù)布爾值的真?zhèn)?,?zhí)行不同的語(yǔ)句。
if (expression)
statement;
// 或者
if (expression) statement;
上面是if
結(jié)構(gòu)的基本形式。需要注意的是,expression(表達(dá)式)必須放在圓括號(hào)中,表示對(duì)表達(dá)式求值。如果結(jié)果為true
,就執(zhí)行緊跟在后面的語(yǔ)句(statement);如果結(jié)果為false
,則跳過(guò)statement的部分。
if (m === 3)
m += 1;
上面代碼表示,只有在m
等于3時(shí),才會(huì)將其值加上1。
這種寫(xiě)法要求條件表達(dá)式后面只能有一個(gè)語(yǔ)句。如果想執(zhí)行多個(gè)語(yǔ)句,必須在if
的條件判斷之后,加上大括號(hào),表示代碼塊。
if (m === 3) {
m += 1;
}
建議總是在if
語(yǔ)句中使用大括號(hào),因?yàn)檫@樣方便插入語(yǔ)句。
注意,if
后面的表達(dá)式,不要混淆“賦值表達(dá)式”(=
)與“嚴(yán)格相等運(yùn)算符”(===
)或“相等運(yùn)算符”(==
)。因?yàn)?,“賦值表達(dá)式”不具有比較作用。
var x = 1;
var y = 2;
if (x = y) {
console.log(x);
}
// "2"
上面代碼的原意是,當(dāng)x
等于y
的時(shí)候,才執(zhí)行相關(guān)語(yǔ)句。但是,不小心將“嚴(yán)格相等運(yùn)算符”寫(xiě)成“賦值表達(dá)式”,結(jié)果變成了將y
賦值給x
,然后條件就變成了,變量x
的值(等于2)自動(dòng)轉(zhuǎn)為布爾值以后,判斷其是否為true
。
這種錯(cuò)誤可以正常生成一個(gè)布爾值,因而不會(huì)報(bào)錯(cuò)。為了避免這種情況,有些開(kāi)發(fā)者習(xí)慣將常量寫(xiě)在運(yùn)算符的左邊,這樣的話,一旦不小心將相等運(yùn)算符寫(xiě)成賦值運(yùn)算符,就會(huì)報(bào)錯(cuò),因?yàn)槌A坎荒鼙毁x值。
if (x = 2) { // 不報(bào)錯(cuò)
if (2 = x) { // 報(bào)錯(cuò)
至于為什么優(yōu)先采用“嚴(yán)格相等運(yùn)算符”(===
),而不是“相等運(yùn)算符”(==
),請(qǐng)參考《運(yùn)算符》一節(jié)。
if
代碼塊后面,還可以跟一個(gè)else
代碼塊,表示不滿(mǎn)足條件時(shí),所要執(zhí)行的代碼。
if (m === 3) {
// then
} else {
// else
}
上面代碼判斷變量m
是否等于3,如果等于就執(zhí)行if
代碼塊,否則執(zhí)行else
代碼塊。
對(duì)同一個(gè)變量進(jìn)行多次判斷時(shí),多個(gè)if...else
語(yǔ)句可以連寫(xiě)在一起。
if (m === 0) {
// ...
} else if (m === 1) {
// ...
} else if (m === 2) {
// ...
} else {
// ...
}
else
代碼塊總是跟隨離自己最近的那個(gè)if
語(yǔ)句。
var m = 1;
var n = 2;
if (m !== 1)
if (n === 2) console.log('hello');
else console.log('world');
上面代碼不會(huì)有任何輸出,else
代碼塊不會(huì)得到執(zhí)行,因?yàn)樗氖亲罱哪莻€(gè)if
語(yǔ)句,相當(dāng)于下面這樣。
if (m !== 1) {
if (n === 2) {
console.log('hello');
} else {
console.log('world');
}
}
如果想讓else
代碼塊跟隨最上面的那個(gè)if
語(yǔ)句,就要改變大括號(hào)的位置。
if (m !== 1) {
if (n === 2) {
console.log('hello');
}
} else {
console.log('world');
}
// world
多個(gè)if...else
連在一起使用的時(shí)候,可以轉(zhuǎn)為使用更方便的switch
結(jié)構(gòu)。
switch (fruit) {
case "banana":
// ...
break;
case "apple":
// ...
break;
default:
// ...
}
上面代碼根據(jù)變量fruit
的值,選擇執(zhí)行相應(yīng)的case
。如果所有case
都不符合,則執(zhí)行最后的default
部分。需要注意的是,每個(gè)case
代碼塊內(nèi)部的break
語(yǔ)句不能少,否則會(huì)接下去執(zhí)行下一個(gè)case
代碼塊,而不是跳出switch
結(jié)構(gòu)。
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
代碼塊之中沒(méi)有break
語(yǔ)句,導(dǎo)致不會(huì)跳出switch
結(jié)構(gòu),而會(huì)一直執(zhí)行下去。
switch
語(yǔ)句部分和case
語(yǔ)句部分,都可以使用表達(dá)式。
switch(1 + 3) {
case 2 + 2:
f();
break;
default:
neverhappens();
}
上面代碼的default
部分,是永遠(yuǎn)不會(huì)執(zhí)行到的。
需要注意的是,switch
語(yǔ)句后面的表達(dá)式與case
語(yǔ)句后面的表示式,在比較運(yùn)行結(jié)果時(shí),采用的是嚴(yán)格相等運(yùn)算符(===
),而不是相等運(yùn)算符(==
),這意味著比較時(shí)不會(huì)發(fā)生類(lèi)型轉(zhuǎn)換。
var x = 1;
switch (x) {
case true:
console.log('x發(fā)生類(lèi)型轉(zhuǎn)換');
default:
console.log('x沒(méi)有發(fā)生類(lèi)型轉(zhuǎn)換');
}
// x沒(méi)有發(fā)生類(lèi)型轉(zhuǎn)換
上面代碼中,由于變量x
沒(méi)有發(fā)生類(lèi)型轉(zhuǎn)換,所以不會(huì)執(zhí)行case true
的情況。這表明,switch
語(yǔ)句內(nèi)部采用的是“嚴(yán)格相等運(yùn)算符”,詳細(xì)解釋請(qǐng)參考《運(yùn)算符》一節(jié)。
JavaScript還有一個(gè)三元運(yùn)算符(即該運(yùn)算符需要三個(gè)運(yùn)算子)?:
,也可以用于邏輯判斷。
(condition) ? expr1 : expr2
上面代碼中,如果condition
為true
,則返回expr1
的值,否則返回expr2
的值。
var even = (n % 2 === 0) ? true : false;
上面代碼中,如果n
可以被2整除,則even
等于true
,否則等于false
。它等同于下面的形式。
var even;
if (n % 2 === 0) {
even = true;
} else {
even = false;
}
這個(gè)三元運(yùn)算符可以被視為if...else...
的簡(jiǎn)寫(xiě)形式,因此可以用于多種場(chǎng)合。
var myVar;
console.log( myVar
? 'myVar has a value'
: 'myVar do not has a value'
)
// myVar do not has a value
上面代碼利用三元運(yùn)算符,輸出相應(yīng)的提示。
var msg = 'The number '
+ n
+ ' is '
+ ((n % 2 === 0) ? 'even' : 'odd');
上面代碼利用三元運(yùn)算符,在字符串之中插入不同的值。
循環(huán)語(yǔ)句用于重復(fù)執(zhí)行某個(gè)操作,它有多種形式。
While
語(yǔ)句包括一個(gè)循環(huán)條件和一段代碼塊,只要條件為真,就不斷循環(huán)執(zhí)行代碼塊。
while (expression)
statement;
// 或者
while (expression) statement;
while
語(yǔ)句的循環(huán)條件是一個(gè)表達(dá)式(express),必須放在圓括號(hào)中。代碼塊部分,如果只有一條語(yǔ)句(statement),可以省略大括號(hào),否則就必須加上大括號(hào)。
while (expression) {
statement;
}
下面是while
語(yǔ)句的一個(gè)例子。
var i = 0;
while (i < 100) {
console.log('i當(dāng)前為:' + i);
i += 1;
}
上面的代碼將循環(huán)100次,直到i
等于100為止。
下面的例子是一個(gè)無(wú)限循環(huán),因?yàn)闂l件總是為真。
while (true) {
console.log('Hello, world');
}
for
語(yǔ)句是循環(huán)命令的另一種形式,可以指定循環(huán)的起點(diǎn)、終點(diǎn)和終止條件。它的格式如下。
for (initialize; test; increment)
statement
// 或者
for (initialize; test; increment) {
statement
}
for
語(yǔ)句后面的括號(hào)里面,有三個(gè)表達(dá)式。
下面是一個(gè)例子。
var x = 3;
for (var i = 0; i < x; i++) {
console.log(i);
}
// 0
// 1
// 2
上面代碼中,初始化表達(dá)式是var i = 0
,即初始化一個(gè)變量i
;測(cè)試表達(dá)式是i < x
,即只要i
小于x
,就會(huì)執(zhí)行循環(huán);遞增表達(dá)式是i++
,即每次循環(huán)結(jié)束后,i
增大1。
所有for
循環(huán),都可以改寫(xiě)成while
循環(huán)。上面的例子改為while
循環(huán),代碼如下。
var x = 3;
var i = 0;
while (i < x) {
console.log(i);
i++;
}
for
語(yǔ)句的三個(gè)部分(initialize,test,increment),可以省略任何一個(gè),也可以全部省略。
for ( ; ; ){
console.log('Hello World');
}
上面代碼省略了for
語(yǔ)句表達(dá)式的三個(gè)部分,結(jié)果就導(dǎo)致了一個(gè)無(wú)限循環(huán)。
do...while
循環(huán)與while
循環(huán)類(lèi)似,唯一的區(qū)別就是先運(yùn)行一次循環(huán)體,然后判斷循環(huán)條件。
do
statement
while (expression);
// 或者
do {
statement
} while (expression);
不管條件是否為真,do..while
循環(huán)至少運(yùn)行一次,這是這種結(jié)構(gòu)最大的特點(diǎn)。另外,while
語(yǔ)句后面的分號(hào)不能省略。
下面是一個(gè)例子。
var x = 3;
var i = 0;
do {
console.log(i);
i++;
} while(i < x);
break
語(yǔ)句和continue
語(yǔ)句都具有跳轉(zhuǎn)作用,可以讓代碼不按既有的順序執(zhí)行。
break
語(yǔ)句用于跳出代碼塊或循環(huán)。
var i = 0;
while(i < 100) {
console.log('i當(dāng)前為:' + i);
i++;
if (i === 10) break;
}
上面代碼只會(huì)執(zhí)行10次循環(huán),一旦i
等于10,就會(huì)跳出循環(huán)。
for
循環(huán)也可以使用break
語(yǔ)句跳出循環(huán)。
for (var i = 0; i < 5; i++) {
console.log(i);
if (i === 3)
break;
}
// 0
// 1
// 2
// 3
上面代碼執(zhí)行到i
等于3,就會(huì)跳出循環(huán)。
continue
語(yǔ)句用于立即終止本輪循環(huán),返回循環(huán)結(jié)構(gòu)的頭部,開(kāi)始下一輪循環(huán)。
var i = 0;
while (i < 100){
i++;
if (i%2 === 0) continue;
console.log('i當(dāng)前為:' + i);
}
上面代碼只有在i
為奇數(shù)時(shí),才會(huì)輸出i
的值。如果i
為偶數(shù),則直接進(jìn)入下一輪循環(huán)。
如果存在多重循環(huán),不帶參數(shù)的break
語(yǔ)句和continue
語(yǔ)句都只針對(duì)最內(nèi)層循環(huán)。
JavaScript語(yǔ)言允許,語(yǔ)句的前面有標(biāo)簽(label),相當(dāng)于定位符,用于跳轉(zhuǎn)到程序的任意位置,標(biāo)簽的格式如下。
label:
statement
標(biāo)簽可以是任意的標(biāo)識(shí)符,但是不能是保留字,語(yǔ)句部分可以是任意語(yǔ)句。
標(biāo)簽通常與break
語(yǔ)句和continue
語(yǔ)句配合使用,跳出特定的循環(huán)。
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
上面代碼為一個(gè)雙重循環(huán)區(qū)塊,break
命令后面加上了top
標(biāo)簽(注意,top
不用加引號(hào)),滿(mǎn)足條件時(shí),直接跳出雙層循環(huán)。如果break
語(yǔ)句后面不使用標(biāo)簽,則只能跳出內(nèi)層循環(huán),進(jìn)入下一次的外層循環(huán)。
continue
語(yǔ)句也可以與標(biāo)簽配合使用。
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
命令后面有一個(gè)標(biāo)簽名,滿(mǎn)足條件時(shí),會(huì)跳過(guò)當(dāng)前循環(huán),直接進(jìn)入下一輪外層循環(huán)。如果continue
語(yǔ)句后面不使用標(biāo)簽,則只能進(jìn)入下一輪的內(nèi)層循環(huán)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: