JS學習筆記(第5章)(引用類型)

引用類型的值(對象)是引用類型的一個實例,引用類型是一種數據結構,用於將數據和功能組織在一塊兒。引用類型有時候也被稱爲對象定義,由於他們描述的是一類對象所具備的屬性和方法。對象是某個特定引用類型的實例,新對象是使用new操做符後跟一個構造函數來建立。前端

var  person = new Object();

5.1 Object類型

1. 建立Object實例
建立Object實例的方式有兩種:
(1)使用new操做符後跟Object構造函數正則表達式

var person = new Object();
person.name = "Chris";
person.age = 22;

(2)使用對象字面量表示法express

var person = {
name : "Chris",
age : 22
};

注意:
1) 在對象字面量中,使用逗號來分隔不一樣的屬性,但在最後一個屬性後面不能添加逗號。不然在一些早 版本瀏覽器中致使錯誤。
2)在使用對象字面量語法時,屬性名也可使用字符串;
3)使用對象字面量語法時,若是留空其花括號,則能夠定義只包含默認屬性和方法的對象,以下:segmentfault

var person = {};
person.name = "Chris";
person.age = 22;

2. 訪問對象屬性
(1)點表示法windows

alert(person.name);  //"Chris"

(2)方括號表示法數組

alert(person["name"]);  //"Chris"

注意:1)方括號表示法的主要優勢是能夠經過變量來訪問屬性;瀏覽器

var propertyName = "name";
 alert(person[propertyName]);  //"Chris"

2)若是屬性名中包含會致使語法錯誤的字符,或者屬性名使用的是關鍵字或者保留字,也可使用方括號表示法;數據結構

person["first name"] = "Chris";

由於"first name"中包含一個空格,因此不能讓使用點表示法來訪問它們,然而,屬性名中是能夠包含非字母非數字的,這時候就可使用方括號表示法來訪問它們;
3)一般,除非必須使用變量來訪問屬性,不然建議使用點表示法。app

5.2 Array類型

一、與其餘語言不一樣的是:
(1)ECMScript數組的每一項能夠保存任何類型的數據;
(2)ECMScript數組的大小是能夠動態調整的,便可以隨着數據的添加自動增加以容納新增數據;
二、建立數組的基本方式有兩種:
(1)使用Array構造函數;函數

var colors = new Array();

(2)使用數組字面量表示法,數組字面量由一對包含數組項的方括號表示,多個數組之間以逗號隔開;

var colors = ["red", "blue", "yellow"];

三、在讀取和設置數組的值時,要使用方括號並提供相應值的基於0的數字索引;

var colors = ["red", "blue", "green"] //定義一個字符串數組`
alert(colors[0]); //顯示第一項
colors[2] = "black";  //修改第三項
colors[3] = "brown";  //新增第四項

四、數組的項數保存在其length屬性中,這個屬性始終會返回0或更大的值;

var colors = ["red", "blue", "green"]; //定義一個字符串數組
alert(colors.length);  //3

五、經過設置數組的length屬性,能夠從數組的末尾移除項或者向數組中添加新項;

var colors = ["red", "blue", "green"] //定義一個字符串數組
colors.length = 2;
alert(colors[2]);  //undefined(移除項)

該例中的數組colors一開始有3個值,將其length屬性設置爲2會移除最後一項(位置爲2的那一項),結果再訪問colors[2]就會顯示undefined。若是將其length屬性設置爲大於數組項數的值,則新增的每一項都回去的undefined值;

var colors = ["red", "blue", "green"] //定義一個字符串數組
colors.length = 4;
alert(colors[3]);  //undefined(新增項)

利用length屬性也能夠方便地在數組末尾添加新項;

var colors = ["red", "blue", "green"] //定義一個字符串數組
colors[colors.length] = "black";  //(在位置3)添加一種顏色
colors[colors.length] = "brown";  //(在位置4)再添加一種顏色

當把一個值放在超出當前數組大小的位置上時,數組就會從新計算其長度值,即長度值等於最後一項的索引加1。
1. 檢測數組
(1)對於一個網頁或者有個全局做用域而言,使用instanceof操做符就能肯定某個對象是否是數組;

if (value instanceof Array) {
   //對數組執行某些操做
}

(2)Array.isArray()方法的目的是最終肯定某個值究竟是不是數組,而無論它是在哪一個全局執行環境中建立的。

if (Array.isArray(value)) {
  //對數組執行某些操做
}

2. 轉換方法
全部對象都具備toLocaleString()toString()valueOf()方法。其中,調用valueOf()返回的仍是數組自己,而調用數組的toString()方法會返回有數組中每一個值的字符串形式拼接而成的一個以逗號分隔的字符串;
toLocalString()方法常常會返回與toString()和valueOf()方法相同的值,但也不老是如此。
數組繼承的toLocaleString()、toString()和valueOf()方法,在默認狀況下都會以逗號分隔的字符串的形式返回數組項,而若是使用join()方法,則可使用不一樣的分隔符來構建這個字符串(將數組轉化爲字符串)。join()方法只接收一個參數,即用做分隔符的字符串,而後返回包含全部數組項的字符串.若是不給join()方法傳入任何值,或者給它傳入undefined,則使用逗號做爲分隔符。

var colors = ["red", "green", "blue"];
alert(colors.join(","));  //red,green,blue
alert(colors.join("||"));  //red||green||blue

3. 棧方法
棧是一種LIFO(Last-In-First-Out,先進後出)的數據結構,也就是最新添加的項最先被移除。而棧中項的插入(叫作推入)和移除(叫作彈出),只發生在一個位置——棧的頂部。
push()方法能夠接收任意數量的參數,把它們逐個添加到數組末尾,並返回修改後數組的長度;
pop()方法從數組末尾移除最後一項,減小數組的length值,而後返回移除的項;

var colors = new Array();  //建立一個數組
var count = colors.push("red", "green");  //推入兩項
alert(count);  //2

var item = colors.pop(); //取得最後一項
alter(item);  //"green"
alert(colors.length); //1

4. 隊列方法
隊列數據結構的訪問規則是FIFO(First-In-First-Out,先進先出)。隊列在列表的末端添加項,從列表的前端移除項;
(1)shift()方法,它可以移除數組中的第一項並返回該項,同時將數組長度減1(刪除第一項);
(2)unshift()方法,它能在數組前端添加任意個項並返回新數組的長度。
(3)結合使用shift()和push()方法,能夠像使用隊列同樣使用數組;(末端添加項,前端移除項)

var colors = new Array(); //建立一個數組
var count = colors.push("red", "green"); //推入兩項
alert(count);  //2

count = colors.push("black");  //末端推入另外一項

var item = colors.shift();  //取得第一項
alert(item); //"red" 
alert(colors.length);  //2
(4)同時使用unshift()和pop()方法,能夠從相反的方向來模擬隊列;(前端添加項,末端移除項)
var colors = new Array(); //建立一個數組`
var count = colors.push("red", "green"); //推入兩項
alert(count);  //2

count = colors.unshift("black");  //前端推入另外一項

var item = colors.pop();  //取得最後一項
alert(item); //"green" 
alert(colors.length);  //2

5. 重排序方法
(1)數組中已經存在的兩個能夠直接用重排序的方法:reverse()sort()方法
reverse()方法會反轉數組項的順序;
在默認狀況下,sort()方法按升序排列數組項,sort()方法會調用每一個數組項的toString()轉型方法,而後比較獲得字符串,已肯定如何排序,即便數組中的每一項都是數值,sort()方法比較的也是字符串。
(2)比較函數(P93)
6. 操做方法
(1)concat()方法能夠基於當前數組中的全部項建立一個新的數組
(2)slice()方法可以基於當前數組中的一個多個項建立一個新的數組。slice()方法能夠接收一個或者兩個參數,即要返回項的起始和結束位置。在只有一個參數的狀況下,slice()方法返回從該參數指定位置開始到當前數組末尾的全部項;若是有兩個參數,該方法返回起始和結束位置之間的項——但不包括結束位子的項。注意,slice()方法不會影響原始數組。

var colors = ["red", "green", "blue", "yellow","purple"];
var colors2 = colors.silce(1);
var colors3 = colors.slice(1,4);

alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow

注意:
1)若是slice方法的參數中有一個附屬,則用數組長度加上該數來肯定相應的位置;
2)若是結束位置小於起始位置,則返回空數組
(3)splice()方法的主要用途是向數組的中部插入項
1)刪除:能夠刪除任意數量的項,只需指定2個參數:splice(要刪除的第一項的位置,要刪除的項數)
2)插入:能夠向指定位置插入任意數量的項,只需提供3個參數splice(起始位置,要刪除的項數,要插入的項)
3)替換:能夠向指定位置插入任意數量的項,且同時刪除任意數量的項,只需指定3個參數
splice(起始位置,要刪除的項數,要插入的任意數量的項),插入的項數沒必要與刪除的項數相等;

var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1)    //刪除第一項
alert(colors);  //green,blue
alert(removed); //red,返回的數組中只包含一項

removed = colors.splice(1,0,"yellow","orange");  //從位置1開始插入兩項
alert(colors);  //green,yellow,orange,blue
alert(removed);  //返回的是一個空數組

removed = colors.splice(1,1,"red","purple");   //插入兩項,刪除一項
alert(colors); //green,red,purple,orange,blue
alert(removed); //yellow,返回的數組中只包含一項

7. 位置方法
indexOf()lastIndexOf(),這兩個方法都接收兩個參數:要查找的項和(可選的)表示查找起點位置的索引。其中,indexOf()方法從數組的開頭(位置0 )開始向後查找。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

8. 迭代方法
每一個方法都接收兩個參數:要在每一項運行的函數和(可選的)運行該函數的做用域對象。傳入這些方法中的函數會接收三個參數:數組項的值、該項在數組中的位置和數組對象自己。

  • every():對數組中的每一項運行給定函數,若是該函數對每一項都返回true,則返回true;
  • filter():對數組中的每一項運行給定函數,返回該函數會返回true的項組成的數組;
  • forEach():對數組中的每一項運行給定函數,該方法沒有返回值;
  • map():對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組;
  • some():對數組中的每一項運行給定函數,若是該函數對任一項返回true,則返回true。

注意:對every()來講,傳入的函數必須對每一項都返回true,這個方法才返回true;而some()方法則是隻要傳入的函數對數組中的某一項返回true,就會返回true。

9. 歸併方法
ECMAScript5新增了兩個歸併數組的方法:reduce()和reduceRight()。這兩個方法都會迭代數組的全部項,而後構建一個最終返回值。其中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

5.3 Date類型

要建立一個日期對象,使用new操做符和Date構造函數便可
var now = new Date();
//在調用Date構造函數而不傳遞參數的狀況下,新建立的對象自動得到當前日期和時間
若是想根據特定的日期和時間建立日期對象,必須傳入該日期的毫秒數。或者使用Date.parse()Date.UTC();
Date.parse()方法接收一個表示日期的字符串參數,而後嘗試根據這個字符串返回相應日期的毫秒數;若是傳入Date.parse()方法的字符串不能表示日期,那麼它會返回NaN;若是直接將表示日期的字符串傳遞給Date構造函數,也會在後臺調用Date.parse()。
Date.UTC()方法一樣也返回表示日期的毫秒數,Date.UTC()的參數分別是年份、基於0的月份,月中的哪一天(1到31)、小時數(0到23)、分鐘、秒以及毫秒數。在這些參數中,只有年和月是必需的
Date.now()方法,返回表示調用這個方法時的日期和時間的毫秒數。
1. 繼承的方法
Date類型也重寫了toLocaleString()、toString()和valueOf()方法。

  • Date類型的toLocaleString()方法會按照與瀏覽器設置的時區相適應的格式返回日期和時間。(大體意味時間格式中會包含AM或PM,但不會包含時區信息);
  • Date類型的toString()方法則一般返回帶有時區信息的日期和時間,其中時間通常以軍用時間表示;
  • Date類型的valueOf()方法則根本不返回字符串,而是返回日期的毫秒錶示。所以,能夠方便使用比較操做符(小於或大於)來比較日期值。

2. 日期格式化方法

  • toDateString()——以特定於實現的格式顯示星期幾、月、日和年;
  • toTimeString()——以特定於實現的格式顯示時、分、秒和時區;
  • toLocaleDateString()——以特定於地區的格式顯示星期幾、月、日和年;
  • toLocaleTimeString()——以特定於實現的格式顯示時、分、秒和時區;
  • toUTCString()——以特定於實現的格式完整的UTC日期;

3. 日期/時間組件方法 (P102)

5.4 RegExp類型

RegExp類型是用來支持正則表達式:
(1)第一種建立正則表達式的方法以下:
var expression = / pattern / flags;
其中的模式(pattern)部分能夠是任何簡單或複雜的正則表達式,能夠包含字符類、限定符、分組、向前查找以及反向引用。
每一個正則表達式均可以帶有一個或者多個標誌(flags),用以標明正則表達式的行爲。正則表達式的匹配模式支持下列3個標誌:

  • g:表示全局(global)模式,即模式將被應用於全部字符串,而非在發現第一個匹配項時當即中止;
  • i:表示不區分大小寫(case-insensitive)模式,即在肯定匹配項時忽略模式與字符串的大小寫;
  • m:表示多行(multiline)模式,即在到達一行文本末尾時還會繼續查找下一行是否存在與模式匹配的項

模式中使用的全部元字符都必須轉義。正則表達式中的元字符包括:( [ { ^ $ | ) ? * + . ] }
(2)另外一種建立正則表達式的方式是使用RegExp函數,它接收兩個參數:一個是要匹配的字符串模式,另外一個是可選的標誌字符串。
//匹配第一個"bat"或"cat",不區分大小寫
var pattern1 = /[bc]at/i; //使用第一種方法建立
var pattern2 = new RegExp("[bc]at","i"); //使用RegExp函數實現
因爲RegExp構造函數的模式參數是字符串,因此在某些狀況下要對字符串進行雙重轉義。
1. RegExp實例屬性

  • global:布爾值,表示是否設置了g標誌;
  • ignoreCase:布爾值,表示是否設置了i標誌;
  • lastIndex:整數,表示開始搜索下一個匹配項的字符位置,從0算起。
  • multiline:布爾值,表示是否設置了m標誌;
  • source:正則表達式的字符串表示,按照字面量形式而非傳入構造函數的字符串模式返回。
  • source屬性保存的是規範形式的字符串,即字面量形式所用的字符串。

2. RegExp實例方法
正則表達式的第一個方法是exec()連接描述: 接收一個參數,即要應用模式的字符串,而後返回包含第一個匹配信息的數組;或者在沒有匹配項的狀況下返回null。exec() 方法還返回兩個屬性。index 屬性聲明的是匹配文本的第一個字符的位置(匹配項在字符串中的位置)。input 屬性則存放的是被檢索的字符串 string(表示應用正則表達式的字符串)。
對於exec()方法而言,即便在模式中設置了全局標誌(g),他每次也只會返回一個匹配項。在不設置全局標誌的狀況下,在同一個字符串上屢次調用exec()將始終返回第一個匹配項的信息,而在設置全局變量的狀況下,每次調用exec()則都會在字符串中繼續查找新匹配項。
正則表達式的第二個方法是test()連接描述:它接受一個字符串參數,若是字符串 string 中含有與RegExpObject 匹配的文本,則返回true,不然返回false
3. RegExp構造函數屬性

  • input:最近一次要匹配的字符串["$_"]
  • lastMatch:最近一次與整個正則表達式匹配的字符串["$&"]
  • lastParen:最近一次匹配的捕獲組["$+"]
  • leftContext:input字符串中lastMatch以前的文本["$`"]
  • rightContext:input字符串中lastMatch以後的文本["$'"]
  • multiline:布爾值,表示是否全部表達式都使用多行模式["$*"]
var text = "this has been a short summer";
    var pattern = /(.)hort/g;
    
    if(pattern.test(text)){
    alert(RegExp.input);  //this has been a short summer
    alert(RegExp.leftContext);  //this has been
    alert(RegExp.rightContext);  //summer
    alert(RegExp.lastMatch);  //short
    alert(RegExp.lastParen);  //a
    alert(RegExp.multiline);  //false
    }

注意:以上使用的長屬性名均可以用相應的短屬性名來代替,不太短屬性名不是有效的ECMAScript標識符,所以必須經過方括號語法來訪問它們。

var text = "this has been a short summer";
var pattern = /(.)hort/g;

if(pattern.test(text)){
alert(RegExp.$_);  //this has been a short summer
alert(RegExp["`$`"]);  
//this has been
alert(RegExp["$'"]);  //summer
alert(RegExp["$&"]);  //short
alert(RegExp["$+"]);  //a
alert(RegExp["$*"]);  //false
}

4. 模式的侷限性 (P109)

5.5 Function類型

1. 沒有重載(深刻理解)
2. 函數聲明與函數表達式
3. 做爲值的函數
4. 函數的內部屬性
在函數內部,有兩個特殊的對象:argumentsthis
(1)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*arguements.callee(num-1);
}
}

在這個重寫後的factorial()函數的函數體內,沒有再引用函數名factorial。這樣,不管引用函數時使用的是什麼名字,均可以保證正常完成遞歸調用。
(2)函數內部的另外一個特殊對象是this。this引用的是函數執行的環境對象(當在網頁的全局做用域中調用函數時,this對象引用的就是window)
!函數的名字僅僅是一個包含指針的變量而已
EMAScript也規範了另外一個函數對象的屬性:caller這個屬性保存着 調用當前函數的函數的引用
5. 函數屬性和方法
每一個函數都包含兩個屬性:lengthprototype
(1)length屬性表示函數但願接收的命名參數的個數
(2)prototype屬性是保存他們全部實例方法的真正所在
(3)每一個函數都包含兩個非繼承而來的方法:apply()call(),這兩個方法的用途都是在特定的做用域中調用函數,實際上等於設置函數體內this對象的值。
apply()方法接收兩個參數:在其中運行的函數的做用域 和 參數數組
call()方法:第一個參數是this值沒有變化,變化的是其他參數都直接傳遞給函數。換句話說,在使用call()方法時,傳遞給函數的參數必須逐個列舉出來。

function sum(num1,num2) {
return num1+num2; 
}
function callSum1(num1,num2) {
return sum.apply(this,arguments); //傳入arguments對象
}

function callSum2(num1,num2) {
return sum.apply(this,[num1,num2]); //傳入數組
}

function callSum3(num1,num2) {
return sum.call(this,num1,num2); //其他參數都直接傳遞給函數`
}

alert(callSum1(10,10));  //20
alert(callSum2(10,10));  //20
alert(callSum3(10,10));  //20

apply()和call()真正的用武之地在——可以擴充函數賴以運行的做用域

windows.color = "red";
var o = {color : "blue"};

function sayColor() {
alert(this.color);
}
sayColor();  //red

sayColor.call(this);  //red
sayColor.call(window); //red
sayColor.call(o); //blue

使用apply()或call()來擴充做用於的最大好處就是,對象不須要與方法有任何耦合關係。
(4)bind()方法。這個方法會建立一個函數的實例,其this值會被綁定到傳給bind()函數的值。

windows.color = "red";
var o = {color : "blue"};

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

5.6 基本包裝類型

ECMAScript提供了3種特殊的引用類型:Boolean、Number和String
引用類型與基本包裝類型的主要區別就是對象的生存週期。使用new操做符建立的引用類型的實例,在執行流離開當前做用域以前都一直保存在內存中。而自動建立的基本包裝類型的對象,則只存在於一行代碼的執行瞬間,而後當即被銷燬。這意味着咱們不能在運行時爲基本類型值添加屬性和方法。

var s1 = "some text";
s1.color = "red";
alert(s1.color); //undefined

!注意:使用new調用基本包裝類型的構造函數,與直接調用同名的轉型函數是不同的

var value = "25";
var number = Number(value); //轉型函數
alert(typeof number); //"number"

var obj = new Number(value); //構造函數
alert(type of obj);  //"object"

1. Boolean類型
(1)Boolean類型是與布爾值對應的引用類型。要建立Boolean對象,能夠像下面這樣調用Boolean構造函數並傳入true或者false值。

var BooleanObject= newBoolean(true);

Boolean類型的實例重寫了valueOf()方法,返回基本類型值true或false;重寫了toString()方法,返回字符串"true"和"flase"。

var falseObject = new Boolean(false);
var result = falseObject && true;   
alert(result);  //true 
(布爾表達式中的全部對象都會被轉化爲true,所以falseObject對象在布爾表達式中表明的是true,結果true&&true就等於true)

(2)基本類型與引用類型的布爾值還有兩個區別:
1)typeof操做符對基本類型返回"boolean",而對引用類型返回"object";
2)因爲Boolean對象是Boolean類型的實例,因此使用instanceof操做符測試Boolean對象會返回true,而測試基本類型的布爾值則返回false。

var falseObject = new Boolean(false);
var falseValue = false;
alert(typeof falseObject); //Object
alert(typeof falseValue); //boolean
alert(falseObject instanceof Boolean); //true
alert(falseValue instanceof Boolean); //false

2. Number類型
(1)要建立Number對象,能夠在調用Number構造函數時向其中傳遞相應的數值。

var numberObject = new Number(10);

(2)Number類型也重寫了valueOf()、toLocaleString()和toString()方法。重寫後的valueOf()方法返回對象表示的基本類型的值,另外兩個方法則返回字符串形式的數值。
(3)toFixed()方法會按照指定的小數位返回數值的字符串表示。

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

若是數值自己包含的小數位比指定的還多,那麼接近指定的最大小數位的值就會被舍入。

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

(4)toExponential()可用於格式化數值,該方法返回以指數表示法表示的數值的字符串形式。toExponential()也接收一個參數,並且該參數一樣也是指定輸出結果的小數位數。

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

(5)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類型
連接描述

5.7 單體內置對象

1. Global對象
2. Math對象

5.8 小結

相關文章
相關標籤/搜索