相等操作符
- 相等和不相等
在轉換不同的數據類型時,相等和不想等操作符遵循下面基本規則:
- 如果有一個操作符數是布爾值,則在比較相等性之前先將其轉換為數值——false轉換為0,而true轉換為1;
- 如果一個操作數是字符串,而另一個操作數是數值,在比較相等性之前先將字符串轉化為數值;
- 如果一個操作數是對象,另一個操作數不是,則調用對象的valueOf()方法,用得到的基本類型值按照前面的規則進行比較。
這兩個操作符在進行比較時則要遵循下列規則:- null和undefined是相等的。
- 要比較相等性之前,不能將null和undefined轉換成其他任何只。
- 如果有一個操作數是NaN,則相等操作符返回false,而不相等操作符返回true。即使兩個操作數都是NaN,相等操作符也返回false,因為按照規則,NaN不等於NaN.
- 如果兩個操作數都是對象,則比較它們是不是同一個對象。如果兩個操作數都指向同一個對象,則相等操作符返回true;否則,返回false。
- 全等和不全等
全等操作符由3個等於好(===)表示,它只在兩個操作數未經轉換就相等的情況下返回true,如下:
var result1 =("55"==55);// true,因為轉換后相等var result2 =("55"===55);// false,因為不同數據類型不相等
語句
- for-in語句
for-in語句是一種精准的迭代語句,可以用來枚舉對象的屬性。for-in語句的語法:
for (property in expression) statement
ECMAScript對象的屬性沒有順序,因此,通過for-in循環輸出的屬性名的順序是不可預測的,所有屬性都會被返回一次,但返回的先后次序可能會因瀏覽器而異。 - with語句
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對象是否由同名的屬性,如果發現了同名屬性,則以location對象屬性的值作為變量的值。
嚴格模式下不允許使用with語句,否則將視為語法錯誤。
有序大量使用with語句會導致性能下降,同時也會給調試代碼造成困難,因此在開發大型應用程序時,不建議使用with語句。
函數
ECMAScript中的函數在定義時不必指定是否返回值。函數在任何時候都可以通過return語句后跟要反悔的值來實現返回值。位於return語句之后的任何代碼都永遠不會執行,例如:
function sum(num1,num2){return num1 + num2;alert("Hello world");// 永遠不會執行}
一個函數也可以包含多個return語句,例如:
function diff(num1,num2){if(num1 < num2){return num2 - num1;}else{return num1 - num2;}}
這個函數用於計算兩個數值的差。
另外,return語句也可以不帶有任何的返回值。這種情況下,函數在停止執行后返回undefined值。這種做法一般用在需要提前停止函數執行而不需要返回值的情況下。
function sayHi(name,message){return;alert("Hello "+ name +","+ message);// 永遠不會執行}
推薦的做法是要么讓函數始終都返回一個值,要么永遠都不要返回值。
嚴格模式對函數的一些限制:
- 不能把函數命名為eval或arguments;
- 不能把參數命名為eval或arguments;
-
不能出現兩個命名參數同名的情況。
如果發生以上情況,就會導致語法錯誤。
-
理解參數:
ECMAScript函數不介意傳遞來多少個參數,也不在乎傳進來參數是什么數據類型。原因是ECMAScript中的參數在內部使用一個數組表示的。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數(如果有參數的話。),實際上,在函數體內可以通過arguments對象來訪問這個參數數組,從而獲取傳遞給函數的每一個參數。
arguments對象只是與數組類似(它並不是Array的實例),因為可以使用方括號方位它的每一個元素,使用length屬性來確定傳遞進來多少個參數。
前面的例子中,sayHi()函數的第一個參數名字叫name,而該參數的值也可以通過訪問argument[0]來獲取。因此,函數可以被改寫為:
function sayHi(){alert("Hello "+ arguments[0]+","+ arguments[1]);}
這個事例反映了ECMAScript函數的一個重要特點:命名的參數只提供便利,但不是必需的。
通過訪問arguments對象的length屬性可以獲知有多少個參數傳遞給了函數,可以利用這點讓函數能夠接收人一個參數並分別實現適當的功能。
function doAdd(){if(arguments.length ==1){alert(arguments[0]+10);}elseif(arguments.length ==2){alert(arguments[0]+ arguments[1]);}}doAdd(10);// 20doAdd(30,20);// 50
arguments對象可以與命名參數一起用,如:
function doAdd(num1,num2){if(arguments.length ==1){alert(num1 +10);}elseif(arguments.length ==2){alert(arguments[0]+ num2);}}
arguments的值永遠與對應命名參數的值保持同步,例如:
function doAdd(num1,num2){arguments[1]=10;alert(arguments[0]+ num2);}
每次執行doAdd()函數都會重寫第二個參數,將其改為10.但這種影響是單向的,修改命名參數不會改變arguments中對應的值。如果只傳入一個參數,那么為arguments[1]設置的值不會反映到命名參數。
沒有傳遞值的命名參數將自動被賦予undefined值。例如,如果只給doAdd()函數傳遞了一個參數,則num2中就會自動保存undefined值。
嚴格模式下,不能像前面例子哪樣賦值,會無效,就是說,即使將arguments[1]設置為10,num2的值仍然還是undefined。重寫arguments的值會導致語法錯誤(代碼將不會執行)。
ECMAScript中的所有參數傳遞的都是值,不可能通過引用傳遞參數。
- ECMAScript函數沒有重載
如果在ECMAScript中定義了兩個名字相同的函數,則該名字只屬於后定義的函數。
function addSomeNumber(num){return num +100;}function addSomeNumber(num){return num +200;}var result = addSomeNumber(100);// 300
如前所述,通過檢查傳入函數中參數的類型和數量並作出不同的反應,可以模仿方法的重載。
ECMAScript中的函數與其他語言中的函數有諸多不同之處:
- 無須指定函數的返回值,因為任何ECMAScript函數都可以在任何時候返回任何值。
- 實際上,未指定返回值的函數返回的是一個特殊的undefined值。
- ECMAScript中也沒有函數簽名的概念,因為其函數參數是以一個包含零或多個值的數組的形式傳遞的。
- 可以想ECMAScript函數傳遞任意數量的參數,並且可以通過arguments對象來訪問這些參數。
- 由於不存在函數簽名的特性,ECMAScript函數不能重載。
