書中第3章 基本概念摘要(三) express
3.6 語句
3.6.1 if 語句
if(condition) statement1 else statement2
3.6.2 do-while 語句
do{
statement
}while(expression)
3.6.3 while 語句
while(expression) statement
3.6.4 for 語句
for(initialization; expression; post-loop-expression) statement
在for循環的變量初始化表達式中,也能夠不使用var關鍵字。該變量的初始化能夠在外部執行,例如:
var count = 10;
var i;
for(i=0;i<count;i++){
alert(i);
}
以上代碼與在循環初始化表達式中聲明變量的效果是同樣的。因爲ECMAScript中不存在塊級做用域,所以在循環內部定義的變量也能夠在外部訪問到。例如:
var count = 10;
for(var i=0;i<count;i++){
alert(i);
}
alert(i); //10
在這個例子中,會有一個警告框顯示循環完成後變量 i 的值,這個值是10。這是由於,即便 i 是在循環內部定義的一個變量,但在循環外部仍然能夠訪問到它。
3.6.5 for-in 語句
for-in 語句是一種精準的迭代語句,能夠用來枚舉對象的屬性。
for(property in expression) statement
示例:
for(var propName in window){
document.write(propName);
document.write('<br/>');
}
ECMAScript對象的屬性沒有順序,所以,經過for-in循環輸出的屬性名的順序是不可預測的。具體來說,因此屬性都會被返回一次,但返回的前後次序可能會因瀏覽器而異。(Safari3 之前版本的for-in語句中存在一個bug,該bug會致使某些屬性被返回兩次)
3.6.6 label語句
label: statement
示例:
start: for(var i=0;i<count;i++){
alert(i);
}
這個例子中定義的start標籤能夠在未來由break或continue語句引用。加標籤的語句通常都要與for語句等循環語句配合使用。
3.6.7 break 和 continue 語句
break語句示例:
var num = 0;
for(var i=1;i<10;i++){
if(i%5==0){
break;
}
num++;
}
alert(num); //4
continue語句示例:
var num = 0;
for(var i=1;i<10;i++){
if(i%5==0){
continue;
}
num++;
}
alert(num); //8
break語句結合label語句聯合使用:
var num = 0;
outermost:
for(var i=1;i<10;i++){
for(var j=0;j<10;j++){
if(i==5 && j==5){
break outermost;
}
num++;
}
}
alert(num); //55
continue語句結合label語句聯合使用:
var num = 0;
outermost:
for(var i=1;i<10;i++){
for(var j=0;j<10;j++){
if(i==5 && j==5){
continue outermost;
}
num++;
}
}
alert(num); //95
3.6.8 with語句
with語句的做用是將代碼的做用域設置到一個特定的對象中。
with(expression) statement
數組
定義with語句的目的主要是爲了簡化屢次編寫同一個對象的工做,以下面的例子所示:
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
上面幾行代碼都包含location對象,若是使用with語句,能夠把上面的代碼改寫成以下所示:
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
在這個重寫後的例子中,使用with語句關聯了location對象。這意味着在with語句的代碼塊內部,每一個變量首先被認爲是一個局部變量,而若是在局部環境中找不到該變量的定義,就會查詢location對象中是否有同名的屬性。若是發現了同名屬性,則以location對象屬性的值做爲變量的值。(因爲大量使用with語句會致使性能降低,同時也會給調試代碼速成困難,所以在開發大型應用程序時,不建議使用with語句)
3.6.9 switch 語句
switch(expression){
case value: statement
break;
case value: statement
break;
case value: statement
break;
case value: statement
break;
default: statement
}
ECMAScript中的switch語句借鑑自其它語言,但這個語句也有本身的特點。首先,能夠在switch語句中使用任何數據類型(在不少其它語言中只能使用數值或枚舉),不管是字符串,仍是對象都沒有問題。其次,每一個case的值不必定是常量,能夠是變量,甚至是表達式。以下面這個例子:
switch("hello world"){
case "hello" + "world":
alert("Greeting was found.");
break;
case "goodbye":
alert("Closing was found.");
break;
default:
alert("Unexpected message was found.")
}
結果顯示:Greeting was found.
var num = 25;
switch(true){
case num < 0:
alert("Less than 0.");
break;
case num >= 0 && num <= 10:
alert("Between 0 and 10.");
break;
case num > 10 && num <= 20:
alert("Between 10 and 20.");
break;
default:
alert("More than 20.")
}
結果顯示:More than 20.
這個例子首先在switch語句外面聲明瞭變量num。而之因此給switch語句傳遞表達式true,是由於每一個case值均可以返回一個布爾值。這樣,每一個case按照順序被求值,直到找到配匹的值或者遇到default語句爲止。
switch語句在比較值時使用的是全等操做符,所以不會發生類型轉換(例如,字符串"10"不等於數值10)。
3.7 函數
函數的基本語法:
function functionName(arg0, arg1, ..., argN){
statements
}
示例:
function sayHi(name, message){
alert("Hello " + name + "," + message);
}
調用sayHi()函數的代碼以下:
sayHi("Nicholas", "how are you today?");
輸出結果是"Hello Nicholas,how are you today?".
3.7.1 理解參數
ECMAScript函數的參數與大多數其餘語言中函數的參數有所不一樣。ECMAScript函數不介意傳遞進來多少個參數,也不在意傳進來參數是什麼數據類型。由於ECMAScript中的參數在內部是用一個數組來表示的。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數(若是有參數的話)。若是這個數組中不包含任何元素,無所謂;若是包含多個元素,也沒用問題。實際上,在函數體內能夠經過arguments對象來訪問這個參數數組,從而得到傳遞給函數的每個參數。
其實,arguments對象只是與數組相似(它並非Array的實例)。由於可使用方括號語法訪問它的每個元素(即第一個元素是arguments[0],第二個元素是arguments[1],以此類推),使用length屬性來肯定傳遞進來多少個參數。
上面的sayHi()函數也能夠像下面這樣重寫,即不顯示地使用命名參數:
function sayHi(){
alert("Hello " + arguments[0] + "," + arguments[1]);
}
這個事實說明了ECMAScript函數的一個重要特色:命名的參數只提供便利,但不是必需的。
function howManyArgs(){
alert(arguments.length);
}
howManyArgs("string", 45); //2
howManyArgs(); //0
howManyArgs(12); //1
因而可知,開發人員能夠利用這一點讓函數可以接收任意個參數並分別實現適當的功能。例如:
function doAdd(){
if(arguments.length == 1){
alert(arguments[0] + 10);
}else if(arguments.length == 2){
alert(arguments[0] + arguments[1]);
}
}
doAdd(10); //20
doAdd(30, 20); //50
另外一個與參數相關的重要方面,就是arguments對象能夠與命名參數一塊兒使用,例如:
function doAdd(num1, num2){
if(arguments.length == 1){
alert(num1 + 10);
}else if(arguments.length == 2){
alert(arguments[0] + num2);
}
}
doAdd(10); //20
doAdd(30, 20); //50
關於參數還要記住最後一點:沒有傳遞值的命名參數將自動被賦予undefined值。這就跟定義了變量但又沒有初始化同樣。例如,若是隻給doAdd()函數傳遞了一個參數,則num2中就會保存undefined值。(ECMAScript中的全部參數傳遞的都是值,不可能經過引用傳遞參數)
3.7.2 沒有重載
ECMAScript函數沒有簽名,由於其參數是由包含零或多個值的數組來表示的。而沒有函數簽名,真正的重載是不可能作到的。示例:
function addSomeNumber(num){
return num + 100;
}
function addSomeNumber(num){
return num + 200;
}
var result = addSomeNumber(100);
alert(result); //300
在此,addSomeNumber()被定義了兩次,後定義的函數覆蓋了先定義的函數。
如前所述,經過檢查傳入函數中參數的類型和數量並做出不一樣的反應,能夠模仿方法的重載.
瀏覽器
以上全部內容均摘自圖書《JavaScript 高級程序設計(第2版)》[美] Nicholas C.Zakas 著 李鬆峯 曹力 譯
函數