高程第五章

1.Object類型:

兩種創建實例的方式:1.new操作符創建——var person = new Object(); 2.對象字面量表示法——var person = {name: "Bob", age: 10};

2.Array類型:
  • 創建實例的方法:
    1.new操作符:
var colors = new Array(); // 創建一個空數組
var colors = new Array(20); // 創建一個長度為20的數組
var colors = new Array("red", "green", "blue"); // 創建一個包含三個字符串值的數組

另外,在使用 Array 構造函數時也可以省略 new 操作符。
例如:var colors = Array();
2.數組字面量表示法:

var colors = ["red", "blue", "green"]; // 創建一個包含 3 個字符串的數組
var names = []; // 創建一個空數組
var values = [1,2,]; // 不要這樣!這樣會創建一個包含 2 或 3 項的數組
var options = [,,,,,]; // 不要這樣!這樣會創建一個包含 5 或 6 項的數組

如果設置

var colors = [1, 2, 3];
colors[9] = 999;

那么,數組的長度變為10,其中未定義的項的值為undefined。

  • 檢測數組:
    ??instanceof 操作符的問題在于,它假定只有一個全局執行環境。如果網頁中包含多個框架,那實際上就存在兩個以上不同的全局執行環境,從而存在兩個以上不同版本的 Array 構造函數。如果你從一個框架向另一個框架傳入一個數組,那么傳入的數組與在第二個框架中原生創建的數組分別具有各自不同的構造函數。
    ??為了解決這個問題,ECMAScript 5 新增了 Array.isArray()方法。這個方法的目的是最終確定某個值到底是不是數組,而不管它是在哪個全局執行環境中創建的。
    ??用法:Array.isArray(value)返回一個布爾值。
    ??數組繼承的 toLocaleString()、toString(),在默認情況下都會以逗號分隔的字符串的形式返回數組項,valueOf()方法返回數組并輸出。而如果使用 join()方法,則可以使用不同的分隔符來構建這個字符串。join()方法只接收一個參數,即用作分隔符的字符串,然后返回包含所有數組項的字符串。請看下面的例子:
var colors = ["red", "green", "blue"];
alert(colors.join(",")); //red,green,blue
alert(colors.join("||")); //red||green||blue 
  • 棧方法:
    push():在數組最前端插入一個值,改變原數組的值,返回新數組的長度。
    pop():刪除數組的最后一項,改變原數組的值,返回被刪除的值。
  • 隊列方法:
    shift():刪除數組第一項,改變原數組的值,返回被刪除的值。
    另外,還有一個unshift()方法:在數組前端插入值,改變原數組的值,返回新數組的長度。
  • 重排序方法
    1.reverse():反轉數組項的順序并輸出,改變原數組,返回新數組的值。
    2.sort():默認升序排列。
    ??為了實現排序,sort()方法會調用每個數組項的 toString()轉型方法,然后比較得到的字符串,以確定如何排序。即使數組中的每一項都是數值,sort()方法比較的也是字符串。
  • 操作方法:
    1.concat():連接兩個數組不改變原數組,輸出新數組。
    2.splice():
    ?1.刪除:可以刪除任意數量的項,只需指定 2 個參數:要刪除的第一項的位置和要刪除的項數。例如,splice(0,2)會刪除數組中的前兩項。
    ?2.插入:可以向指定位置插入任意數量的項,只需提供 3 個參數:起始位置、0(要刪除的項數)和要插入的項。如果要插入多個項,可以再傳入第四、第五,以至任意多個項。例如,splice(2,0,"red","green")會從當前數組的位置 2 開始插入字符串"red"和"green"。
    ?3.替換:可以向指定位置插入任意數量的項,且同時刪除任意數量的項,只需指定 3 個參數:起始位置、要刪除的項數和要插入的任意數量的項。插入的項數不必與刪除的項數相等。例如,splice (2,1,"red","green")會刪除當前數組位置 2 的項,然后再從位置 2 開始插入字符串"red"和"green"。
    ??splice()方法始終都會返回一個數組,該數組中包含從原始數組中刪除的項(如果沒有刪除任何項,則返回一個空數組)。
  • 位置方法
    ??indexOf()與lastIndexOf(),這兩個方法都返回要查找的項在數組中的位置,或者在沒找到的情況下返回-1。在比較第一個參數與數組中的每一項時,會使用全等操作符;也就是說,要求查找的項必須嚴格相等(就像使用===一樣)。
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5
alert(numbers.indexOf(4, 4)); //5
alert(numbers.lastIndexOf(4, 4)); //3
var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
alert(people.indexOf(person)); //-1,這里的的兩個對象其實指向不同的指針。
alert(morePeople.indexOf(person)); //0 
  • 迭代方法
    1.every():對數組中的每一項運行給定函數,如果該函數對每一項都返回 true,則返回 true。
    2.filter():對數組中的每一項運行給定函數,返回該函數會返回 true 的項組成的數組。
    3.forEach():對數組中的每一項運行給定函數。這個方法沒有返回值。
    4.map():對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組。
    5.some():對數組中的每一項運行給定函數,如果該函數對任一項返回 true,則返回 true。
    以上方法都不會修改數組中的包含的值。
  • 歸并方法
    ECMAScript 5 還新增了兩個歸并數組的方法:reduce()和reduceRight()。這兩個方法都會迭代數組的所有項,然后構建一個最終返回的值。其中,reduce()方法從數組的第一項開始,逐個遍歷到最后。而 reduceRight()則從數組的最后一項開始,向前遍歷到第一項。
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
 return prev + cur;
});
alert(sum); //15 
3.Date類型

Date類型使用自 UTC(Coordinated Universal Time,國際協調時間)1970 年 1 月 1 日午夜(零時)開始經過的毫秒數來保存日期。
??在調用 Date 構造函數而不傳遞參數的情況下,新創建的對象自動獲得當前日期和時間。如果想根據特定的日期和時間創建日期對象,必須傳入表示該日期的毫秒數(即從 UTC 時間 1970 年 1 月 1 日午夜起至該日期止經過的毫秒數)。為了簡化這一計算過程,ECMAScript 提供了兩個方法:Date.parse()和 Date.UTC()。

4.RegExp類型

1.語法:var expression = / pattern / flags ;
2.正則表達式的匹配模式支持下列 3 個標志。

  • g:表示全局(global)模式,即模式將被應用于所有字符串,而非在發現第一個匹配項時立即停止;
  • i:表示不區分大小寫(case-insensitive)模式,即在確定匹配項時忽略模式與字符串的大小寫;
  • m:表示多行(multiline)模式,即在到達一行文本末尾時還會繼續查找下一行中是否存在與模式匹配的項。
    與其他語言中的正則表達式類似,模式中使用的所有元字符都必須轉義。正則表達式中的元字符包括:
    ( [ { \ ^ $ | ) ? * + .]}
    例如:
/* 匹配第一個"bat"或"cat",不區分大小寫 */ 
var pattern1 = /[bc]at/i;
/*
 匹配第一個" [bc]at",不區分大小寫
*/
var pattern2 = /\[bc\]at/i;
/*
 匹配所有以"at"結尾的 3 個字符的組合,不區分大小寫
*/
var pattern3 = /.at/gi;
/*
 匹配所有".at",不區分大小寫
*/
var pattern4 = /\.at/gi; 

3.正則表達式可以用字面量的形式來定義,也可以通過構造函數方式來定義:

/*
 匹配第一個"bat"或"cat",不區分大小寫
*/
var pattern1 = /[bc]at/i;
/*
 與 pattern1 相同,只不過是使用構造函數創建的
*/
var pattern2 = new RegExp("[bc]at", "i"); 

4.轉義:pattern1 和 pattern2 是兩個完全等價的正則表達式。由于 RegExp 構造函數的模式參數是字符串,所以在某些情況下要對字符進行雙重轉義。所有元字符都必須雙重轉義,那些已經轉義過的字符也是如此,例如\n(字符\在字符串中通常被轉義為\,而在正則表達式字符串中就會變成\\)。下表給出了一些模式,左邊是這些模式的字面量形式,右邊是使用 RegExp 構造函數定義相同模式時使用的字符串:

字面量模式             等價的字符串
/\[bc\]at/            "\\[bc\\]at"
/\.at/                  "\\.at"
/name\/age/           "name\\/age"
/\d.\d{1,2}/          "\\d.\\d{1,2}"
/\w\\hello\\123/   "\\w\\\\hello\\\\123"

5.不同:使用正則表達式字面量和使用 RegExp 構造函數創建的正則表達式不一樣。在 ECMAScript 3 中,正則表達式字面量始終會共享同一個 RegExp 實例,而使用構造函數創建的每一個新 RegExp 實例都是一個新實例。
例子:

var re = null,
 i;
for (i=0; i < 10; i++){
 re = /cat/g;
 re.test("catastrophe");
}
for (i=0; i < 10; i++){
 re = new RegExp("cat", "g");
 re.test("catastrophe");
} 

在第一個循環中,即使是循環體中指定的,但實際上只為/cat/創建了一個 RegExp 實例。由于實例屬性(下一節介紹實例屬性)不會重置,所以在循環中再次調用 test()方法會失敗。這是因為第一次調用 test()找到了"cat",但第二次調用是從索引為 3 的字符(上一次匹配的末尾)開始的,所以就找不到它了。由于會測試到字符串末尾,所以下一次再調用 test()就又從開頭開始了。
??第二個循環使用 RegExp 構造函數在每次循環中創建正則表達式。因為每次迭代都會創建一個新的RegExp 實例,所以每次調用 test()都會返回 true。
6.RegExp實例方法:RegExp 對象的主要方法是 exec(),該方法是專門為捕獲組而設計的

5.Function類型

函數實際上是對象。每個函數都是 Function 類型的實例,而且都與其他引用類型一樣具有屬性和方法。由于函數是對象,因此函數名實際上也是一個指向函數對象的指針,不會與某個函數綁定。
函數聲明語法定義:

function sum(num1, num2) {
    return num1 + num2;
}

函數表達式定義:

var sum = function(num1, num2) {
    return num1 + num2;
}

1.函數沒有重載:后定義的變量覆蓋了先定義的變量。
?2.函數聲明與函數表達式:解析器在向執行環境中加載數據時,對函數聲明和函數表達式并非一視同仁。解析器會率先讀取函數聲明,并使其在執行任何代碼之前可用(可以訪問);至于函數表達式,則必須等到解析器執行到它所在的代碼行,才會真正被解釋執行。

alert(sum(10,10));
function sum(num1, num2){
 return num1 + num2;
}  // 能夠正常運行,存在變量提升
alert(age(1,2));
var age = function(num1, num2) {
  return num1 - num2; 
} // 不能正常運行,會導致“unexpected identifier”(意外標識符)錯誤

3.要訪問函數的指針而不執行函數的話,必須去掉函數名后面的那對圓括號
?4.函數內部屬性:在函數內部,有兩個特殊的對象:arguments 和 this。arguments是一個類數組對象,包含著傳入函數中的所有參數。雖然 arguments 的主要用途是保存函數參數,但這個對象還有一個名叫 callee 的屬性,該屬性是一個指針,指向擁有這個 arguments 對象的函數。

function factorial(num){
 if (num <=1) {
 return 1;
 } else {
 return num * factorial(num-1)
 }
} 
// 等同于
function factorial(num){
 if (num <=1) {
 return 1;
 } else {
 return num * arguments.callee(num-1)
 }
} // 消除了函數執行與函數名之間的緊密耦合

5.函數的屬性和方法:
??ECMAScript 中的函數是對象,因此函數也有屬性和方法。每個函數都包含兩個屬性:length 和 prototype。其中,length 屬性表示函數希望接收的命名參數的個數。對于ECMAScript 中的引用類型而言,prototype 是保存它們所有實例方法的真正所在。換句話說,諸如toString()和 valueOf()等方法實際上都保存在 prototype 名下,只不過是通過各自對象的實例訪問罷了。prototype 屬性是不可枚舉的,因此使用 for-in 無法發現。
??每個函數都包含兩個非繼承而來的方法:apply()和 call()。這兩個方法的用途都是在特定的作用域中調用函數,實際上等于設置函數體內 this 對象的值。首先,apply()方法接收兩個參數:一個是在其中運行函數的作用域,另一個是參數數組。其中,第二個參數可以是 Array 的實例,也可以是arguments 對象。在使用 call()方法的情況下,必須明確地傳入每一個參數。結果與使用 apply()沒有什么不同。
??ECMAScript 5 還定義了一個方法:bind()。這個方法會創建一個函數的實例,其 this 值會被綁定到傳給 bind()函數的值。例如:

window.color = "red";
var o = { color: "blue" };
function sayColor(){
 alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue 

每個函數繼承的 toLocaleString()和 toString()方法始終都返回函數的代碼。返回代碼的格式則因瀏覽器而異。

5.基本包裝類型

為了便于操作基本類型值,ECMAScript 還提供了 3 個特殊的引用類型:Boolean、Number 和String。這些類型與本章介紹的其他引用類型相似,但同時也具有與各自的基本類型相應的特殊行為。實際上,每當讀取一個基本類型值的時候,后臺就會創建一個對應的基本包裝類型的對象,從而讓我們能夠調用一些方法來操作這些數據。
??我們知道,基本類型值不是對象,因而從邏輯上講它們不應該有方法,但實際上他們卻擁有方法,是因為在讀取模式中訪問字符串時,后臺都會自動完成下列處理:
??(1) 創建 String 類型的一個實例;
??(2) 在實例上調用指定的方法;
??(3) 銷毀這個實例。
??上面這三個步驟也分別適用于 Boolean和 Number 類型對應的布爾值和數字值。引用類型與基本包裝類型的主要區別就是對象的生存期。使用 new 操作符創建的引用類型的實例,在執行流離開當前作用域之前都一直保存在內存中。而自動創建的基本包裝類型的對象,則只存在于一行代碼的執行瞬間,然后立即被銷毀。這意味著我們不能在運行時為基本類型值添加屬性和方法。
?1.Boolean類型:Boolean 類型的實例重寫了valueOf()方法,返回基本類型值true 或false;重寫了toString()方法,返回字符串"true"和"false"。
?2.Number類型:與 Boolean 類型一樣,Number 類型也重寫了 valueOf()、toLocaleString()和 toString()方法。重寫后的 valueOf()方法返回對象表示的基本類型的數值,另外兩個方法則返回字符串形式的數值。可以為 toString()方法傳遞一個表示基數的參數,告訴它返回幾進制
數值的字符串形式。
?除了繼承的方法之外,Number 類型還提供了一些用于將數值格式化為字符串的方法。其中,toFixed()方法會按照指定的小數位返回數值的字符串表示,例如:

var num = 10;
alert(num.toFixed(2)); //"10.00" 

如果數值本身包含的小數位比指定的還多,那么接近指定的最大小數位的值就會舍入,如下面的例子所示。

var num = 10.005;
alert(num.toFixed(2)); //"10.01" 

能夠自動舍入的特性,使得 toFixed()方法很適合處理貨幣值。在給 toFixed()傳入 0 的情況下,IE8 及之前版本不能正確舍入范圍在{(-0.94,-0.5],[0.5,0.94)}之間的值。對于這個范圍內的值,IE 會返回 0,而不是-1 或 1;其他瀏覽器都能返回正確的值。IE9 修復了這個問題。
??另外可用于格式化數值的方法是 toExponential(),該方法返回以指數表示法(也稱 e 表示法)表示的數值的字符串形式。

var num = 10;
alert(num.toExponential(1)); //"1.0e+1" 

如果你想得到表示某個數值的最合適的格式,就應該使用 toPrecision()方法。對于一個數值來說,toPrecision()方法可能會返回固定大小(fixed)格式,也可能返回指數(exponential)格式;具體規則是看哪種格式最合適。這個方法接收一個參數,即表示數值的所有數字的位數(不包括指數部分)。請看下面的例子。

var num = 99;
alert(num.toPrecision(1)); //"1e+2"
alert(num.toPrecision(2)); //"99"
alert(num.toPrecision(3)); //"99.0" 

3.String類型:
??1.字符方法:兩個用于訪問字符串中特定字符的方法是:charAt()和 charCodeAt()。這兩個方法都接收一個參數,即基于 0 的字符位置。其中,charAt()方法以單字符字符串的形式返回給定位置的那個字符(ECMAScript 中沒有字符類型)。例如:

var stringValue = "hello world";
alert(stringValue.charAt(1)); //"e"

字符串"hello world"位置 1 處的字符是"e",因此調用 charAt(1)就返回了"e"。如果你想得到的不是字符而是字符編碼,那么就要像下面這樣使用 charCodeAt()了。

var stringValue = "hello world";
alert(stringValue.charCodeAt(1)); //輸出"101"

這個例子輸出的是"101",也就是小寫字母"e"的字符編碼。
ECMAScript 5 還定義了另一個訪問個別字符的方法。在支持此方法的瀏覽器中,可以使用方括號加數字索引來訪問字符串中的特定字符,如下面的例子所示。

var stringValue = "hello world";
alert(stringValue[1]); //"e" 

2.字符串操作方法:第一個就是 concat(),用于將一或多個字符串拼接起來,返回拼接得到的新字符串。ECMAScript還提供了三個基于子字符串創建新字符串的方法:slice()、substr()和 substring()。這三個方法都會返回被操作字符串的一個子字符串,而且也都接受一或兩個參數。第一個參數指定子字符串的開始位置,第二個參數(在指定的情況下)表示子字符串到哪里結束。具體來說,slice()和substring()的第二個參數指定的是子字符串最后一個字符后面的位置。而 substr()的第二個參數指定的則是返回的字符個數。如果沒有給這些方法傳遞第二個參數,則將字符串的長度作為結束位置。與concat()方法一樣,slice()、substr()和 substring()也不會修改字符串本身的值——它們只是返回一個基本類型的字符串值,對原始字符串沒有任何影響。請看下面的例子。

var stringValue = "hello world";
alert(stringValue.slice(3)); //"lo world"
alert(stringValue.substring(3)); //"lo world"
alert(stringValue.substr(3)); //"lo world"
alert(stringValue.slice(3, 7)); //"lo w" 包含開頭不包含結尾
alert(stringValue.substring(3,7)); //"lo w"
alert(stringValue.substr(3, 7)); //"lo worl" 

在傳遞給這些方法的參數是負值的情況下,它們的行為就不盡相同了。其中,slice()方法會將傳入的負值與字符串的長度相加,substr()方法將負的第一個參數加上字符串的長度,而將負的第二個參數轉換為 0。最后,substring()方法會把所有負值參數都轉換為 0。下面來看例子。

var stringValue = "hello world";
alert(stringValue.slice(-3)); //"rld"
alert(stringValue.substring(-3)); //"hello world"
alert(stringValue.substr(-3)); //"rld"
alert(stringValue.slice(3, -4)); //"lo w"
alert(stringValue.substring(3, -4)); //"hel"
alert(stringValue.substr(3, -4)); //""(空字符串)

3.字符串位置方法:有兩個可以從字符串中查找子字符串的方法:indexOf()和 lastIndexOf()。這兩個方法都是從一個字符串中搜索給定的子字符串,然后返子字符串的位置(如果沒有找到該子字符串,則返回-1)。這兩個方法的區別在于:indexOf()方法從字符串的開頭向后搜索子字符串,而 lastIndexOf()方法是從字符串的末尾向前搜索子字符串。還是來看一個例子吧。

var stringValue = "hello world";
alert(stringValue.indexOf("o")); //4
alert(stringValue.lastIndexOf("o")); //7 

這兩個方法都可以接收可選的第二個參數,表示從字符串中的哪個位置開始搜索。換句話說,indexOf()會從該參數指定的位置向后搜索,忽略該位置之前的所有字符;而 lastIndexOf()則會從指定的位置向前搜索,忽略該位置之后的所有字符。看下面的例子。

var stringValue = "hello world";
alert(stringValue.indexOf("o", 6)); //7
alert(stringValue.lastIndexOf("o", 6)); //4 

4.trim()方法:ECMAScript 5 為所有字符串定義了 trim()方法。這個方法會創建一個字符串的副本,刪除前置及后綴的所有空格,然后返回結果。例如:

var stringValue = " hello world ";
var trimmedStringValue = stringValue.trim();
alert(stringValue); //" hello world "
alert(trimmedStringValue); //"hello world" 

5.字符串大小寫轉換的方法:ECMAScript 中涉及字符串大小寫轉換的方法有 4 個:toLowerCase()、toLocaleLowerCase()、toUpperCase()和toLocaleUpperCase()。toLocaleLowerCase()和toLocaleUpperCase()方法則是針對特定地區的實現。對有些地區來說,針對地區的方法與其通用方法得到的結果相同,但少數語言(如土耳其語)會為 Unicode 大小寫轉換應用特殊的規則,這時候就必須使用針對地區的方法來保證實現正確的轉換。

var stringValue = "hello world";
alert(stringValue.toLocaleUpperCase()); //"HELLO WORLD"
alert(stringValue.toUpperCase()); //"HELLO WORLD"
alert(stringValue.toLocaleLowerCase()); //"hello world"
alert(stringValue.toLowerCase()); //"hello world" 
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創建并操作數組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,270評論 0 4
  • 引用類型的值時引用類型的一個實例。在ECMAScript中,引用類型是一種數據結構,用于將數據和功能組織在一起。有...
    cooore閱讀 302評論 0 1
  • 第一章: JS簡介 從當初簡單的語言,變成了現在能夠處理復雜計算和交互,擁有閉包、匿名函數, 甚至元編程等...
    LaBaby_閱讀 1,697評論 0 6
  • 第三章 基本概念 3.1 語法 ECMAScript標識符一般采用駝峰大小寫格式,也就是第一個字母小寫,剩下的每個...
    小雄子閱讀 580評論 0 1
  • Chapter 5 引用類型 Object類型 創建Object實例new Object()var person ...
    云之外閱讀 398評論 0 0