《JavaScript高級程序設計》讀書筆記--5-引用類型

object類型

創建objet實例有兩種方式,new操作符後跟object構造函數和使用對象字面量表示法。

//new
var person = new Object();
person.name = "Nicholas";
person.age = 26;

//對象字面量表示法(推薦這種方法)
var person = {
    name : "Nicholas",
    age : 26
}

//兩者結合
var person = {};//與new Object()相同
person.name = "Nicholas";
person.age = 26;

對必需值使用命名參數,而使用對象字面量來封裝多個可選參數。
訪問對象屬性時使用的都是點表示法,js中也可以使用方括號表示法來訪問對象的屬性。

alert(person["name"]);
alert(person.name);//兩者都輸出"Nicholas"

方括號的優點是可以通過變量來訪問屬性,如:

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

建議使用點表示法,除非必須使用變量來訪問屬性。

Array類型

數組大小是可以動態調整的。

var colors = new Array();//創建數組方法1,new操作符法
var colors = Array();//也可以省略new操作符
//如果括號中的值爲數值則會創建一個長度爲該數值的數組
//如果爲其他類型的參數則會創建包含該參數的只有一項的數組

var colors = ["red", "blue", "green"];//創建數組方法2,數組字面量表示法
var name = [];//創建空數組

在讀取和設置數組的值時,要使用方括號並提供相應值的基於0的數字索引。
數組的項數保存在其length屬性中,這個屬性始終返回0或者更大的值。可以通過設置length屬性從數組的尾端移除或者向數組中添加新項。

var colors = ["red", "blue", "green"];
colors.length = 2;//移除第二項之後的值
//若設置length大於數組項數,則新增項的值都爲undefined
alert(colors[2]);//undefined

在數組尾部添加新項

var colors = ["red", "blue", "green"];
colors[colors.length] = "black";//在位置3添加black
colors[99] = "brown";
alert(colors.length);//100

數組的最後一項的索引始終都是length-1,因此新項的位置就是length。
向數組的位置99插入一個值,數組的新長度變爲100,而4-98實際上都不存在,訪問他們都將返回undefined。
數組最多可以包含4294967295個項,超出這個上限就會發生異常。
檢測數組

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

轉換方法
所有對象都具有toLocaleString()、toString()和valueOf()方法,其中,調用數組的toString()方法會返回由數組中每個值的字符串形式拼接而成的一個以逗號分隔的字符串。而調用value()方法返回的還是數組。toLocaleString()方法也會創建一個數組值的以逗號分隔的字符串,而與前兩個不同之處在於,爲了取得每一項的值,調用的是每一項的toLocaleSting()方法而不是toString()方法。
join()方法可以使用不同的分隔符來構建字符串,他只接受一個參數,即用作分隔符的字符串,然後返回包含所有數組項的字符串。

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

如果不給join()傳遞任何參數或者給他傳入undefined,則默認使用逗號作爲分隔符。
如果數組中有null項,則上述所有方法返回的結果中以空字符串表示該項的值。
棧方法
LIFO,後進先出
push()方法可以接收任意數量的參數,把他們逐個添加到數組的末尾,並返回修改後數組的長度。而pop()方法則從數組末尾移除最後一項,減少數組的length值,然後返回移除的項。

var colors = new Array();
var count = colors.push("red","green");//推入兩項
alert(count);//2
count = colors.push("black");
alert(count);//3
var item = colors.pop();//取得最後一項
alert(item);//"black"
alert(colors.length);//2

隊列方法
FIFO,先進先出
shift()是能夠移除數組中的第一個項並返回該項,同時數組的長度減1.
結合shift()和push()方法,可以像使用隊列一樣使用數組。

var colors = new Array();
var count = colors.push("red", "green");
alert(count);//2
count = colors.push("black");//從末尾添加
alert(count);//3
var item = colors.shift();//取得第一項,移除首項
alert(item);//"red"
alert(colors.length);//2

unshift()與shift()的用途相反,它能在數組的前端添加任意個項並返回新數組的長度。使用上述兩種方法可以在數組的前端添加項,在數組的末端移除項。

var colors = new Array();
var count = colors.unshift("red", "green");//推入兩項
alert(count);//2
count = colors.unshift("black");//在數組前端添加black
alert(count);//3
var item = colors.pop();//從末尾移除
alert(item);//"green"
alert(colors.length);//2

重排序方法
reverse()方法會對數組項的順序進行反轉。
sort()方法按升序排列數組項–即最小的置位於最前面,最大的值位於最後面。sort()方法比較的是數組中每一項的字符串形式,先將每個數組項toString()轉型,再比較得到的字符串。sort()中比較5和10,會將10放在5的前面。
這種情況下sort()方法可以接收一個比較函數作爲參數,以便指定哪個值位於哪個值的前面,比較函數接收兩個參數,若第一個參數應該位於第二個參數之前則返回一個負數,若兩個參數相等則返回0,若第一個參數應該位於第二個參數之後則返回一個正數。

function compare(value1,value2){
        return -1;
    }else if(value1 > value2){
        return 1;
    }else{
        return 0;
    }
}
var values = [0,1,5,10,15];
values.sort(compare);
alert(values);//0,1,5,10,15

若要降序排序,只要交換比較函數返回的值即可。
對於數值類型或者其valueOf()返回數值類型的對象類型,比較函數可以寫成:

function compare(value1,value2){
    return value1-value2;//升序
    //return value2-value1;降序
}

操作方法
concat()方法可以基於當前數組中的所有項創建一個新數組,具體說就是會先創建當前數組的一個副本,然後將接收到的參數添加到這個副本的末尾,最後返回新構建的數組。

var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
alert(colors);//red,green,blue
alert(colors2);//red,green,blue,yellow,black,brown

slice()方法,能夠基於當前數組中的一個或者多個項創建一個新數組,可以接受一個或者兩個參數,即要返回項的起始和結束位置。在只有一個參數的情況下,返回從該參數指定位置開始到當前數組末尾的所有項,如果有兩個參數則返回起始和結束位置之間的項但不包括結束位置的項。注意,該方法不會影響原始數組。
如果參數中有一個負數,則用數組長度加上該數來確定相應的位置,,如果結束位置小於起始位置,則返回空數組。
splice()方法,主要用途是向數組的中部插入項,3種使用方式:

  • 刪除:可以刪除任意數量的項,只需指定2個參數:要刪除的第一項的位置和要刪除的項數。splice(0,2)會刪除數組中的前兩項。
  • 插入:可以向指定位置插入任意數量的項,只需提供3個參數:起始位置、0(要刪除的項數)和要插入的項。splice(2,0,”red”,”green”)會從當前數組的位置2開始插入字符串“red”和“green”。
  • 替換:可以向指定位置插入任意數量的項,且同時刪除任意數量的項,只需指定3個參數:起始位置、要刪除的項數和藥、要插入的任意數量的項。插入和刪除數量不必相等。splice(2,1,”red”,”green”)會刪除當前數組位置2的項然後再從位置2開始插入字符串”red”,”green”。
    splice方法始終返回一個數組,該數組包含從原始數組中刪除的項(若沒有刪除項則返回空數組)。
    位置方法
    indexOf()方法從數組開頭(位置0)開始向後查找。
    lastIndexOf()方法從數組的末尾開始向前查找。
    兩種方法返回要查詢項在數組中的位置,沒找到則返回-1.
    迭代方法
  • every():對數組中的每一項運行給定函數,如果該函數對每一項都返回true,則返回true。
  • filter():對數組中的每一項運行給定函數,返回該函數會返回true的項組成的數組。
  • forEach():對數組中的每一項運行給定函數,沒有返回值。
  • map():對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組。
  • some():對數組中的每一項執行給定函數,如果該函數對任一項返回true,則返回true。
    以上方法都不會修改數組中的包含的值。
var numbers = [1,2,3,4,5,4,3,2,1];
var everResult = numbers.every(function(item,index,array){
    return(item>2);
});
alert(everyResult);//false

var someResule = numbers.some(function(item,index,array){
    return(item>2);
});
alert(someResult);//true

var filterResult = numbers.filer(function(item,index,array){
    return(item>2);
});
alert(fliterResult);//[3,4,5,3]

var mapResult = numbers.map(function(item,index,array){
    return item*2;
});
alert(mapResult);//[2,4,6,8,10,8,6,4,2]

最後一個方法是forEach()方法,他只是對數組中的每一項運行傳入的函數,沒有返回值,本質上與使用for循環迭代數組一樣。

numbers.forEach(function(item,index,array){
    //執行操作
});

縮小方法
reduce()方法從數組的第一項開始逐個遍歷到最後。
reduceRight()方法則從數組的最後一項開始,向前遍歷到第一項。
這兩個方法都回迭代數組的所有項,然後構建一個最終返回的值。
使用reduce還是reduceRight,主要取決於從哪頭開始遍歷,其他完全相同。

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index,array){
    return pre + cur;
});
alert(sum);//15

解析:迭代函數的四個參數分別是前一個值、當前值、項的索引和數組對象。這個函數返回的任何值都回作爲第一個參數自動傳給下一項,第一次迭代發生在數組的第二項上,因此第一個參數就是數組的第一項,第二個參數就是數組的第二項。

Date類型

Date類型保存的日期能夠精確到1970年1月1日之前或者之後的285616年。
創建一個日期對象

var now = new Date();

創建指定日期的一個日期對象

var someDate = new Date(Date.parse("May 25, 2004"));//創建2004年5月25日的日期對象
//也可以直接傳遞給Date構造函數
var someDate = new Date("May 25, 2004");

若字符串不能表示日期則返回NaN。
Date.now()方法表示調用這個方法時的日期和時間的毫秒數。
在不支持該方法的瀏覽器中可以使用+操作符把Date對象轉換成字符串,也可以達到同樣的目的。

var start = Date.now();
var start1 = +new Date();//兩者都是取得開始時間,效果相同

繼承的方法
toLocaleString()和toString()方法返回帶有格式的日期和時間。
valueOf()方法返回日期的毫秒錶示。可以用來比較日期值的大小。
日期格式化方法

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

日期/時間組件方法
。。。看原書吧

RegExp類型

通過RegExp類型支持正則表達式

var expression = /pattern/flags;

其中的模式(pattern)部分可以是任何簡單或複雜的正則表達式,可以包含字符類、限定符、分組、向前查找以及反向引用。每個正則表達式都可帶有一個或者多個標誌(flags)用以標明正則表達式的行爲。

  • g表示全局模式,應用於所有字符串而非發現第一個匹配項是立即停止;
  • i表示不區分大小寫模式;
  • 表示多行模式,即在到達一行文本末尾時還會繼續查找下一行中是否存在與模式匹配的項。
var pattern1 = /at/g;//匹配字符串中所有at的實例
var parrent2 = /[bc]at/i;//匹配第一個bat或者cat,不區分大小寫
var parrent3 = /.at/gi;//匹配所有以at結尾的3個字符的組合,不區分大小寫

正則表達式中的元字符包括:
()[]{}\^$|*?+.
若要匹配這些字符則必須要進行轉義。
使用RegExp構造函數

var pattern1 = /[bc]at/i;//匹配第一個bat或者cat,不區分大小寫
var pattern2 = new RegExp("[bc]at","i");//與pattern1一樣!

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。
RegExp屬性

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

RegExp實例方法
exec()方法,專門爲捕獲組而設計的,它接受一個參數,即要應用模式的字符串,然後返回包含第一個匹配項信息的數組;或者在沒有匹配項的情況下返回null。返回的數組雖然是Array實例,但包含兩個額外的屬性:index和input。index表示匹配項在字符串的位置,而input表示應用正則表達式的字符串。

test()方法,它接收一個字符串參數,在模式與該參數匹配的情況下返回true;否則,返回false。在只想知道目標字符串與某個模式是否匹配但不需要知道其文本內容的情況下使用這個方法很方便。

繼承的toString和toLocaleString方法都會返回正則表達式的字面量。
RegExp構造函數屬性
構造屬性

Function類型

函數實際上可以理解爲對象,每個函數都是Function類型的實例,而且有屬性和方法。
函數名僅僅是指向函數的指針,因此函數名與包含對象指針的其他變量沒有什麼不同,也就是一個函數可能會有多個名字。
沒有重載
函數名相同的兩個函數,後一個函數會覆蓋掉前一個函數。
函數聲明與函數表達式
解析器會率先讀取函數聲明,並使其在執行任何代碼之前可用;至於函數表達式,則必須等到解析器執行到他所在的代碼行,纔會真正被解釋執行。

alert(sum(10,10));
function sum(num1,num2){
    return num1+num2;
}
//可以正常運行

alert(sum(10,10));
var sum = function(num1,num2){
    return num1+num2;
}
//不能正常執行

作爲值的函數

function callSomeFunction(someFunction,someArgument){
    return someFunction(someArgument);
}
function add10(num){
    return num+10;
}
var result = callSomeFunction(add10,10);
alert(result);//20

函數內部屬性
arguments的主要用途是保存函數參數,但這個對象還有一個名叫callee的屬性,該屬性是一個指針,指向擁有這個arguments對象的函數。

function factorial(num){
    if(num<1){
        return 1;
    }else{
        return num * arguments.callee(num-1);
    }
}

這是階乘函數的定義,若函數名字不變的情況也可以使用
return num*factorial(num-1);
但是,這個函數的執行就與函數名緊緊耦合在了一起,使用arguments.callee就消除了這種現象。

this對象,與Java大致類似,this引用的是函數據以執行的環境對象–或者也可以說是this值。

函數屬性和方法
length表示接收參數的個數。
prototype
bind()
call()
apply()
擴充作用域

基本包裝類型
String
Boolean
Number

單體內置對象

Global對象,不屬於任何其他對象的屬性和方法最終都是他的屬性和方法。所有在全局作用域中定義的屬性和函數都是Global對象的屬性。
eval()方法

eval("alert('hello')");
alert("hello");//兩者等價

Math對象
math對象
math方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章