5 引用類型

本章內(nèi)容

  • 使用對(duì)象
  • 創(chuàng)建并操作數(shù)組
  • 理解基本的 JavaScript 類型
  • 使用基本類型和基本包裝類型

引用類型的值(對(duì)象)是引用類型的一個(gè)實(shí)例薛耻。

雖然引用類型與類看起來(lái)相似亡蓉,但它們并不是相同的概念。為避免混淆续徽,本書(shū)將不使用類這個(gè)概念弟劲。

新對(duì)象是使用new操作符跟一個(gè)構(gòu)造函數(shù)來(lái)創(chuàng)建的叮姑。

var person = new Object();

這行代碼創(chuàng)建了Object引用類型的一個(gè)新實(shí)例广料,然后把該實(shí)例保存在了變量person中砾脑。使用的構(gòu)造函數(shù)是Object,它只為新對(duì)象定義了默認(rèn)的屬性和方法艾杏。

5.1 Object 類型

創(chuàng)建Object實(shí)例的方式有兩種韧衣。第一種是使用new操作符后跟Object構(gòu)造函數(shù)。

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

另一種是使用對(duì)象字面量表示法购桑。

var person = {
  name : "Nicholas",
  age : 29
}

在使用對(duì)象字面量語(yǔ)法時(shí)畅铭,屬性名也可以使用字符串。

var person = {
  "name" : "Nicholas",
  "age" : 29,
  5: true
}

這個(gè)例子會(huì)創(chuàng)建一個(gè)對(duì)象勃蜘,包含三個(gè)屬性:name顶瞒、age5元旬。但這里的數(shù)值屬性會(huì)自動(dòng)轉(zhuǎn)換為字符串。
另外守问,使用對(duì)象字面語(yǔ)法時(shí)匀归,如果留空其花括號(hào),則可以定義只包含默認(rèn)屬性和方法的對(duì)象耗帕。

var person = {};  //與new Object()相同
person.name = "Nicholas";
person.age = 29;

開(kāi)發(fā)人員更青睞對(duì)象字面量語(yǔ)法穆端。實(shí)際上,對(duì)象字面量也是向函數(shù)傳遞大量可選參數(shù)的首選方式仿便。

function displayInfo(args) {
  var output = "";
  if (typeof args.name == "string") {
    output += "Name: " + args.name + "\n";
  }
  if (typeof args.age == "number") {
    output += "Age: " + args.age + "\n";
  }
  alert(output);
}

displayInfo({
  name: "Nicholas",
  age: 29
});

displayInfo({
  name: "Greg"
});

這種傳遞參數(shù)的模式最適合需要向函數(shù)傳入大量可選參數(shù)的情形体啰。

一般來(lái)說(shuō)攒巍,訪問(wèn)對(duì)象屬性時(shí)使用的都是點(diǎn)表示法,這也是很多面向?qū)ο笳Z(yǔ)言中通用的語(yǔ)法荒勇。在JavaScript也可以使用方括號(hào)表示來(lái)訪問(wèn)對(duì)象的屬性柒莉。使用方括號(hào)語(yǔ)法時(shí),應(yīng)該將要訪問(wèn)的屬性以字符串形式放在方括號(hào)中沽翔。

alert(person["name"]);  //"Nicholas"
alert(person.name);  //"Nicholas"

從功能上看兢孝,這兩種訪問(wèn)對(duì)象屬性的方法沒(méi)有任何區(qū)別。但方括號(hào)語(yǔ)法的主要優(yōu)點(diǎn)是可以通過(guò)變量來(lái)訪問(wèn)屬性仅偎。

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

通常跨蟹,除非必須使用變量來(lái)訪問(wèn)屬性,否則我們建議使用點(diǎn)表示法橘沥。

5.2 Array 類型

ECMAScript 中的數(shù)組與其他多數(shù)語(yǔ)言中的數(shù)組有著相當(dāng)大的區(qū)別头滔。雖然 ECMAScript 數(shù)組與其他語(yǔ)言中的數(shù)組都是數(shù)據(jù)的有序列表,但與其他語(yǔ)言不同的是包归,ECMAScript 數(shù)組的每一項(xiàng)可以保存任何類型的數(shù)據(jù)案淋。而且,ECMAScript 數(shù)組的大小是可以動(dòng)態(tài)調(diào)整的箫措,即可以隨著數(shù)據(jù)的添加自動(dòng)增長(zhǎng)以容納新增數(shù)據(jù)腹备。
創(chuàng)建數(shù)組的基本方式有兩種。第一種是使用Array構(gòu)造函數(shù)斤蔓。

var colors = new Array();

如果預(yù)先知道數(shù)組要保存的項(xiàng)目數(shù)量植酥,也可以給構(gòu)造函數(shù)傳遞該數(shù)量,而該數(shù)量會(huì)自動(dòng)變成length屬性的值弦牡。

var colors = new Array(20);

也可以向Array構(gòu)造函數(shù)傳遞數(shù)組中應(yīng)該包含的項(xiàng)友驮。

var colors = new Array("red", "blue", "green");

傳遞一個(gè)值也可以創(chuàng)建數(shù)組。

var colors = new Array(3);  //創(chuàng)建一個(gè)包含3項(xiàng)的數(shù)組
var names = new Array("Greg");  //創(chuàng)建一個(gè)包含1項(xiàng)驾锰,即字符串“Greg”的數(shù)組

創(chuàng)建數(shù)組的第二種基本方式是使用數(shù)組字面量表示法卸留。

var colors = ["red", "blue", "green"];
var names = [];

與對(duì)象一樣,在使用數(shù)組字面量表示法時(shí)椭豫,也不會(huì)調(diào)用Array構(gòu)造函數(shù)耻瑟。

var colors = ["red", "blue", "green"];
alert(colors[0]);
colors[2] = "black";  //修改第三項(xiàng)
colors[3] = "brown";  //新增第四項(xiàng)

數(shù)組的項(xiàng)數(shù)保存在其length屬性中,這個(gè)屬性始終返回0或更大的值赏酥。

var colors = ["red", "blue", "green"];  
var names = [];
alert(colors.length);  //3
alert(names.length);  //0

數(shù)組的length屬性不是只讀的喳整。通過(guò)設(shè)置這個(gè)屬性,可以從數(shù)組的末尾移除或向數(shù)組中添加新項(xiàng)裸扶。

var colors = ["red", "blue", "green"];
colors.length = 2;
alert(colors[2]);  //undefined

利用length屬性也可以方便地在數(shù)組末尾添加新項(xiàng)框都。

var colors = ["red", "blue", "green"];
colors[colors.length] = "black";
colors[colors.length] = "brown";

當(dāng)把一個(gè)值放在超出當(dāng)前數(shù)組大小的位置上時(shí),數(shù)組就會(huì)重新計(jì)算其長(zhǎng)度值呵晨,即長(zhǎng)度值等于最后一項(xiàng)的索引加 1魏保。

var colors = ["red", "blue", "green"];
colors[99] = "black";
alert(colors.length);  //100

數(shù)組位置 3 到位置 98 實(shí)際上都是不存在的熬尺,所以訪問(wèn)它們都將返回undefined

數(shù)組最多可以包含 4294967295 個(gè)項(xiàng)谓罗,這幾乎已經(jīng)能夠滿足任何編程需求了粱哼。

5.2.1 檢測(cè)數(shù)組

ECMAScript 5 新增了Array.isArray()方法。這個(gè)方法的目的是最終確定某個(gè)值到底是不是數(shù)組妥衣,而不管它是在哪個(gè)全局執(zhí)行環(huán)境中創(chuàng)建的皂吮。

if (Array.isArray(value)) {
  //對(duì)數(shù)組執(zhí)行某些操作
}

5.2.2 轉(zhuǎn)換方法

所有方法都具有toLocalString()toString()税手、valueOf()方法蜂筹。其中,調(diào)用數(shù)組的toString()方法會(huì)返回由數(shù)組中每個(gè)值得字符串形式拼接而成的一個(gè)以逗號(hào)分隔的字符串芦倒。而調(diào)用valueOf()返回的還是數(shù)組艺挪。實(shí)際上,為了創(chuàng)建這個(gè)字符串會(huì)調(diào)用數(shù)組每一項(xiàng)的toString()方法兵扬。

var colors = ["red", "blur", "green"];
alert(colors.toString());  //red,blue,green
alert(colors.valueOf());  //red,blue,green
alert(colors);  //red,blue,green

最后一行代碼直接將數(shù)組傳遞給了alert()麻裳。由于alert()要接收字符串參數(shù),所以它會(huì)在后臺(tái)調(diào)用toString()方法器钟,由此會(huì)得到與直接調(diào)用toString()方法相同的結(jié)果津坑。

另外,toLocaleString()方法經(jīng)常也會(huì)返回前兩個(gè)方法相同的值傲霸。與前兩個(gè)方法唯一不同之處在于疆瑰,這一次為了取得每一項(xiàng)的值,調(diào)用的是每一項(xiàng)的toLocaleString()方法昙啄,而不是toString()方法穆役。

var person1 = {
  toLocaleString : function() {
    return "Nikolaos";
  }
  toString : function() {
    return "Nicholas";
  }
};

var person2 = {
  toLocaleString : function() {
    return "Grigorios";
  }
  toString : function() {
    return "Greg";
  }
};

var people = [person1, person2];
alert(people);  //Nicholas,Greg
alert(people.toString());  //Nicholas,Greg
alert(people.toLocaleString());  //Nikolaos,Grigorios

如果使用join()方法,則可以使用不同的分隔符來(lái)構(gòu)建這個(gè)字符串梳凛。join()方法只接收一個(gè)參數(shù)耿币,即用作分隔符的字符串,然后返回包含所有數(shù)組項(xiàng)的字符串韧拒。如果不給join()方法傳入任何值淹接,或者給它傳入undefined,則使用逗號(hào)作為分隔符叛溢。

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

如果數(shù)組中的某一項(xiàng)的值是null或者undefined蹈集,那么該值在join()toLocaleString()雇初、toString()valueOf()方法返回的結(jié)果以空白字符串表示减响。

5.2.3 棧方法

ECMAScript 為數(shù)組專門提供了push()pop()方法靖诗,以便實(shí)現(xiàn)類似棧的行為郭怪。
push()方法可以接收任意數(shù)量的參數(shù),把它們逐個(gè)添加到數(shù)組末尾刊橘,并返回修改后數(shù)組的長(zhǎng)度鄙才。而pop()方法則從數(shù)組末尾移除最后一項(xiàng),減少數(shù)組的length值促绵,然后返回移除的項(xiàng)攒庵。

var colors = new Array();
var count = colors.push("red", "green");
alert(count);  //2
count = colors.push("black");
alert(count);
var item = colors.pop();
alert(item);  //"black"
alert(colors.length);  //2

5.2.4 隊(duì)列方法

棧數(shù)據(jù)結(jié)構(gòu)的訪問(wèn)規(guī)則是LIFO(后進(jìn)先出),而隊(duì)列數(shù)據(jù)結(jié)構(gòu)的訪問(wèn)規(guī)則是FIFO(先進(jìn)先出)败晴。shift()能夠移除數(shù)組中的第一個(gè)項(xiàng)并返回該項(xiàng)浓冒,同時(shí)將數(shù)組長(zhǎng)度減1。結(jié)合使用shift()push()方法尖坤,可以像使用隊(duì)列一樣使用數(shù)組稳懒。

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

ECMAScript還為數(shù)組提供了一個(gè)unshift()方法。它能在數(shù)組前端添加任意個(gè)項(xiàng)并返回新數(shù)組的長(zhǎng)度慢味。因此场梆,同時(shí)使用unshift()pop()方法,可以從相反的方向來(lái)模擬隊(duì)列纯路,即在數(shù)組的前端添加項(xiàng)或油,從數(shù)組末端移除項(xiàng)。

var colors = new Array();
var count = colors.unshift("red", "green");
alert(count);  //2
count = colors.unshift("black");
alert(count);  //3
var item = colors.pop();
alert(item);  //"green"
alert(colors.length);  //2

IE7及更早版本中其unshift()方法總是返回undefined值驰唬。

5.2.5 重排序方法

數(shù)組中已經(jīng)存在兩個(gè)可以直接用來(lái)重排序的方法:reverse()sort()顶岸。

var values = [1, 2, 3, 4, 5];
values.reverse();
alert(values);  //5,4,3,2,1

在默認(rèn)情況下,sort()方法按升序排列數(shù)組項(xiàng)定嗓。sort()方法會(huì)調(diào)用每個(gè)數(shù)組項(xiàng)的toString()轉(zhuǎn)型方法蜕琴,然后比較得到的字符串,以確定如何排序宵溅。

var values = [0, 1, 5, 10, 15];
values.sort();
alert(values);  //0,1,10,15,5

可見(jiàn)凌简,即使例子中值得順序沒(méi)有問(wèn)題,但sort()方法會(huì)根據(jù)測(cè)試字符串的結(jié)果改變?cè)瓉?lái)的順序恃逻。字符串比較時(shí)雏搂,“10”位于“5”的前面。sort()方法可以接收一個(gè)比較函數(shù)作為參數(shù)寇损,以便我們指定那個(gè)值位于那個(gè)值的前面凸郑。
以下就是一個(gè)簡(jiǎn)單的比較函數(shù):

function compare(value, value) {
  if (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

也可以通過(guò)比較函數(shù)產(chǎn)生降序排序的結(jié)果,只要交換比較函數(shù)返回的值即可矛市。

function compare (value1, value2) {
  if (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);  //15,10,5,1,0

對(duì)于數(shù)值類型或者其valueOf()方法會(huì)返回?cái)?shù)值類型的對(duì)象類型芙沥,可以使用一個(gè)更簡(jiǎn)單的比較函數(shù)。這個(gè)函數(shù)只要用第二個(gè)值減第一個(gè)值即可。

function compare(value1, value2) {
  return value2 - value1;
}

5.2.6 操作方法

concat()方法可以基于當(dāng)前數(shù)組中的所有項(xiàng)創(chuàng)建一個(gè)新數(shù)組而昨。具體來(lái)說(shuō)救氯,這個(gè)方法會(huì)先創(chuàng)建當(dāng)前數(shù)組一個(gè)副本,然后將接收到的參數(shù)添加到這個(gè)副本的末尾歌憨,最后返回新構(gòu)建的數(shù)組着憨。在沒(méi)有給concat()方法傳遞參數(shù)的情況下,它只是復(fù)制當(dāng)前數(shù)組并返回副本务嫡。如果傳遞給concat()方法的是一或多個(gè)數(shù)組甲抖,則該方法會(huì)將這些數(shù)組中的每一項(xiàng)都添加到結(jié)果數(shù)組中。如果傳遞的值不是數(shù)組心铃,這些值就會(huì)被簡(jiǎn)單地添加到結(jié)果數(shù)組的末尾准谚。下面來(lái)看一個(gè)例子。

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()能夠基于當(dāng)前數(shù)組中的一或多個(gè)項(xiàng)創(chuàng)建一個(gè)新數(shù)組于个。slice()方法可以接受一或兩個(gè)參數(shù)氛魁,即要返回項(xiàng)的起始和結(jié)束位置。若只有一個(gè)參數(shù)厅篓,slice()方法返回從該參數(shù)指定位置開(kāi)始到當(dāng)前數(shù)組末尾的所有項(xiàng)秀存。如果有兩個(gè)參數(shù),該方法返回起始和結(jié)束位置之間的項(xiàng)——但不包括結(jié)束位置的項(xiàng)羽氮。注意或链,slice()方法不會(huì)影響原始數(shù)組。

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

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

如果slice()方法的參數(shù)中有一個(gè)負(fù)數(shù)档押,則用數(shù)組長(zhǎng)度加上該數(shù)來(lái)確定相應(yīng)的位置澳盐。例如,在一個(gè)包含5項(xiàng)的數(shù)組上調(diào)用slice(-2,-1)與調(diào)用slice(3,4)的到的結(jié)果相同令宿。如果結(jié)束位置小于起始位置叼耙,則返回空數(shù)組。

splice()方法的主要用途是向數(shù)組的中部插入項(xiàng)粒没,但使用這種方法的方式則有如下3種筛婉。

  • 刪除: 可以刪除任意數(shù)量的項(xiàng),只需指定2個(gè)參數(shù):要?jiǎng)h除的第一項(xiàng)的位置和要?jiǎng)h除的項(xiàng)數(shù)癞松。例如爽撒,splice(0,2)會(huì)刪除數(shù)組中的前兩項(xiàng)。
  • 插入:可以向指定位置插入任意數(shù)量的項(xiàng)响蓉,只需提供3個(gè)參數(shù):起始位置硕勿、0(要?jiǎng)h除的項(xiàng)數(shù))和要插入的項(xiàng)。如果要插入多個(gè)項(xiàng)枫甲,可以再傳入第四源武、第五扼褪,以至任意多個(gè)項(xiàng)。例如粱栖,splice(2,0,"red","green")會(huì)從當(dāng)前數(shù)組的位置2開(kāi)始插入字符串“red”和“green”迎捺。
  • 替換: 可以向指定位置插入任意數(shù)項(xiàng)的項(xiàng),且同時(shí)刪除任意數(shù)量的項(xiàng)查排,只需指定3個(gè)參數(shù):起始位置、要?jiǎng)h除的項(xiàng)數(shù)和要插入的任意數(shù)量的項(xiàng)抄沮。插入的項(xiàng)數(shù)不必與刪除的項(xiàng)數(shù)相等跋核。例如,splice(2,1,"red","green")會(huì)刪除當(dāng)前數(shù)組位置2的項(xiàng)叛买,然后自從位置2開(kāi)始插入字符串“red”和“green”砂代。

splice方法始終都會(huì)返回一個(gè)數(shù)組,該數(shù)組中包含從原始數(shù)組中刪除的項(xiàng)(如果沒(méi)有刪除任何項(xiàng)率挣,則返回一個(gè)空數(shù)組)刻伊。下面的代碼展示了上述3種使用splice()方法的方式。

var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1);  //刪除第一項(xiàng)
alert(colors);  //green, blue
alert(removed);  //red

removed = colors.splice(1, 0, "yellow", "orange");  //從位置1開(kāi)始插入兩項(xiàng)
alert(colors);  //green,yellow,yellow,orange,blue
alert(removed);  //返回的是一個(gè)空數(shù)組

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

5.2.7 位置方法

ECMAScript5 為數(shù)組實(shí)例添加了兩個(gè)位置方法: indexOf()lastIndexOf()捶箱。這兩個(gè)方法都接收兩個(gè)參數(shù):要查找的項(xiàng)和(可選的)表示查找起點(diǎn)位置的索引。indexOf()方法從數(shù)組的開(kāi)頭(位置0)開(kāi)始向后查找动漾。lastIndexOf()方法則從數(shù)組的末尾開(kāi)始向前查找丁屎。
這倆方法都返回要查找的項(xiàng)在數(shù)組中的位置,或者在沒(méi)找到的情況下返回-1.在比較第一個(gè)參數(shù)與數(shù)組中的每一項(xiàng)時(shí)旱眯,會(huì)使用全等操作符晨川。

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

var person = {name: "Nicholas"};
var people = [{name: "Nicholas"}];
var morePeople = [person];
alert(people.indexOf(person));  //-1
alert(morePeople.indexOf(person));  //0

5.2.8 迭代方法

ECMAScript5 為數(shù)組定義了5個(gè)迭代方法。每個(gè)方法都接收兩個(gè)參數(shù):要在每一項(xiàng)上運(yùn)行的函數(shù)和(可選的)運(yùn)行該函數(shù)的作用域?qū)ο蟆绊?code>this的值删豺。傳入這些方法中的函數(shù)會(huì)接收三個(gè)參數(shù):數(shù)組項(xiàng)的值共虑、該項(xiàng)在數(shù)組中的位置和數(shù)組對(duì)象本身。

  • every():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)呀页,如果該函數(shù)對(duì)每一項(xiàng)都返回true妈拌,則返回true
  • filter():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)赔桌,返回該函數(shù)會(huì)返回true的項(xiàng)組成的數(shù)組供炎。
  • forEach():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)。這個(gè)方法無(wú)返回值疾党。
  • map():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)音诫,返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。
  • some():對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)雪位,如果該函數(shù)對(duì)任一項(xiàng)返回true竭钝,則返回true
    以上方法都不會(huì)修改數(shù)組中的包含的值。
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array) {
  return (item > 2);
});
alert(everyResult);  //false
var someResult = numbers.some(function(item, index, array) {
  return (item > 2);
});
alert(someResult);  //true
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array) {
  return(item > 2);
});
alert(filterResult);  //[3,4,5,4,3]
var numbers = [1,2,3,4,5,4,3,2,1];

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

forEach()這個(gè)方法沒(méi)有返回值香罐,只是對(duì)數(shù)組中的每一項(xiàng)運(yùn)行傳入的函數(shù)本質(zhì)上與使用for循環(huán)迭代數(shù)組一樣卧波。

var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array) {
  //執(zhí)行某些操作
});

5.2.9 縮小方法

ECMAScript 5 新增了倆縮小數(shù)組的方法:reduce()reduceRight。這倆方法都會(huì)迭代數(shù)組的所有想庇茫,然后構(gòu)建一個(gè)最終返回的值港粱。其中,reduce()方法從數(shù)組的第一項(xiàng)開(kāi)始旦签,逐個(gè)遍歷到最后查坪。而reduceRight()則從數(shù)組的最后一項(xiàng)開(kāi)始,向前遍歷到第一項(xiàng)宁炫。
這倆方法都接收兩個(gè)參數(shù):一個(gè)在每一項(xiàng)調(diào)用的函數(shù)和(可選)作為縮小基礎(chǔ)的初始值偿曙。傳給reduce()reduceRight()的函數(shù)接收 4 個(gè)參數(shù):前一個(gè)值、當(dāng)前項(xiàng)羔巢、項(xiàng)的索引和數(shù)組對(duì)象望忆。這個(gè)函數(shù)返回的任何值都會(huì)作為第一個(gè)參數(shù)自動(dòng)傳給下一項(xiàng)。第一次迭代發(fā)生在數(shù)組的第二項(xiàng)竿秆,因此第一個(gè)參數(shù)是數(shù)組的第一項(xiàng)启摄,第二個(gè)參數(shù)就是數(shù)組的第二項(xiàng)。
使用reduce()方法可以執(zhí)行求數(shù)組中所有值之和的操作袍辞。

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

5.3 Date 類型

Date類型使用自 UTC 1970 年 1 月 1 日 零時(shí)開(kāi)始經(jīng)過(guò)的毫秒數(shù)來(lái)保存日期鞋仍。
使用new操作符和Date構(gòu)造函數(shù)即可。

var now = new Date();

如果想根據(jù)特定的日期和時(shí)間創(chuàng)建日期對(duì)象搅吁,必須傳入表示該日期的毫秒數(shù)威创。為了簡(jiǎn)化計(jì)算過(guò)程,提供了倆方法:Date.parse()Date.UTC()谎懦。
Date.parse()方法接收一個(gè)表示日期的字符串參數(shù)肚豺,然后嘗試根據(jù)這個(gè)字符串返回相應(yīng)日期的毫秒數(shù)。
如果傳入的字符串不能表示日期界拦,那么它會(huì)返回NaN吸申。實(shí)際上,如果直接將表示日期的字符串傳遞給Date構(gòu)造函數(shù)享甸,也會(huì)在后臺(tái)調(diào)用Date.parse()截碴。

var someDate = new Date("May 25, 2004");

Date.UTC()方法同樣返回表示日期的毫秒數(shù),但它與Date.parse()在構(gòu)建時(shí)使用不同的信息蛉威。參數(shù)分別是年份日丹、基于0的月份,月中的哪一天蚯嫌、小時(shí)數(shù)(0到23)哲虾、分鐘丙躏、秒以及毫秒數(shù)。這些參數(shù)中束凑,只有前兩個(gè)參數(shù)是必須的晒旅。如果沒(méi)有提供月中天數(shù),擇假設(shè)天數(shù)為1汪诉;如果省略其他參數(shù)废恋,則統(tǒng)統(tǒng)假設(shè)為0。

var y2k = new Date(Date.UTC(2000, 0));

var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));

Date構(gòu)造函數(shù)也會(huì)模仿Date.UTC(),但有一點(diǎn)明顯不同:日期和時(shí)間都基于本地時(shí)區(qū)而非GMT來(lái)創(chuàng)建扒寄。
ECMAScript 5 添加了Date.now()方法拴签,返回表示調(diào)用這個(gè)方法時(shí)的日期和時(shí)間的毫秒數(shù)。這個(gè)方法簡(jiǎn)化了使用Date對(duì)象分析代碼的工作旗们。

var start = Date.now();

doSomething();

var stop = Date.now(),
result = stop - start;

5.3.1 繼承的方法

與其他引用類型一樣,Date類型也重寫了toLocaleString()构灸、toString()valueOf()方法上渴;但這些方法返回的值與其他類型中的方法不同。Date類型的 toLocaleString()方法會(huì)按照與瀏覽器設(shè)置的地區(qū)相適應(yīng)的格式返回日期和時(shí)間喜颁。而toString()方法則通常會(huì)返回帶有時(shí)區(qū)信息的日期和時(shí)間稠氮,其中時(shí)間一般以軍用時(shí)間(0到23)表示。
至于Date類型的valueOf()方法半开,則根本不返回字符串隔披,而是返回日期的毫秒表示。因此寂拆,可以方便使用比較操作符來(lái)比較日期值奢米。

var date1 = new Date(2007, 0, 1);
var date2 = new Date(2007, 1, 1);

alert(date1 < date2); //true
alert(date1 > date2);  //false

5.3.2 日期格式化方法

Date類型還有一些專門用于將日期格式化為字符串的方法。

  • toDateString()——以特定于實(shí)現(xiàn)的格式顯示星期幾纠永、月鬓长、日和年;
  • toTimeString()——以特定于實(shí)現(xiàn)的格式顯示時(shí)尝江、分涉波、秒和時(shí)區(qū);
  • toLocaleDateString()——以特定于地區(qū)的格式顯示星期幾炭序、月啤覆、日和年;
  • toLocaleTimeString()——以特定于實(shí)現(xiàn)的格式顯示時(shí)惭聂、分窗声、秒;
  • toUTCString()——以特定于實(shí)現(xiàn)的格式完整的UTC日期彼妻。

以上這些字符串格式方法的輸出也是因?yàn)g覽器而異的嫌佑,因此沒(méi)有哪一個(gè)方法能夠用來(lái)在用戶界面中顯示一致的日期信息豆茫。

5.3.3 日期/時(shí)間組件方法

方法 說(shuō)明
getTime() 返回表示日期的毫秒數(shù);與valueOf()方法返回的值相同
setTime(毫秒) 以毫秒數(shù)設(shè)置日期屋摇,會(huì)改變整個(gè)日期
getFullYear() 取的4位數(shù)的年份
getUTCFullYear() 返回UTC日期的4位數(shù)年份
getMonth() 返回日期的月份揩魂,其中0表示一月
getUTCMonth() 。炮温。火脉。
setMonth(月) 設(shè)置日期的月份,必須大于0柒啤,超過(guò)11增加年份
setUTCMonth(月)
getDate() 返回日期月份中的天數(shù)
getUTCDate()
setDate(日) 設(shè)置日期月份中的天數(shù)倦挂。如果傳入的值超過(guò)了該月中應(yīng)有的天數(shù),則增加月份
setUTCDate()
getDay() 返回日期中星期的星期幾(其中0表示星期日担巩,6表示星期六)
getUTCDay()
getHours() 返回日期中的小時(shí)數(shù)(0到23)
getUTCHours()
setHours(時(shí)) 設(shè)置日期中的小時(shí)數(shù)方援。傳入的值超過(guò)了23則增加月份中的天數(shù)
setUTCHours(時(shí))
getMinutes() 返回日期中的分鐘數(shù)
getUTCMinutes()
setMinutes(分) 設(shè)置日期中的分鐘數(shù)。傳入的值超過(guò)59則增加小時(shí)數(shù)
setUTCMinutes(分)
getSeconds() 返回日期中的秒數(shù)
getUTCSeconds()
setSeconds(秒) 設(shè)置日期中的秒數(shù)涛癌。傳入的值超過(guò)了59會(huì)增加分鐘數(shù)
setUTCSeconds(秒)
getMilliseconds() 返回日期中的毫秒數(shù)
getUTCMilliseconds()
setMilliseconds(毫秒) 設(shè)置日期中的毫秒數(shù)
setUTCMilliseconds(毫秒)
getTimezoneOffset() 返回本地時(shí)間與UTC時(shí)間相差的分鐘數(shù)犯戏。

5.4 RegExp 類型

ECMAScript通過(guò)RegExp類型來(lái)支持正則表達(dá)式。

var expression = / pattern / flags ;

其中的模式(pattern)部分可以是任何簡(jiǎn)單或復(fù)雜的正則表達(dá)式拳话,可以包含字符類先匪、限定類、分組弃衍、向前查找以及反向引用呀非。每個(gè)正則表達(dá)式都可帶有一或多個(gè)標(biāo)志(flags),用以標(biāo)明正則表達(dá)式的行為镜盯。正則表達(dá)式的匹配模式支持下列3個(gè)標(biāo)志岸裙。

  • g: 表示全局模式,即模式將被應(yīng)用于所有字符串速缆,而非在發(fā)現(xiàn)第一個(gè)匹配項(xiàng)時(shí)立即停止哥桥;
  • i:表示不區(qū)分大小寫模式,即再確定匹配時(shí)忽略模式與字符串的大小寫激涤;
  • m:表示多行模式拟糕,即在到達(dá)一行文本末尾時(shí)還會(huì)繼續(xù)查找下一行中是否存在與模式匹配的項(xiàng)。

因此倦踢,一個(gè)正則表達(dá)式就是一個(gè)模式與上述3個(gè)標(biāo)志的組合體送滞。不同組合產(chǎn)生不同結(jié)果。

//匹配字符串中所有“at”的實(shí)例
var pattern1 = /at/g;
//匹配第一個(gè)“bat”或“cat”,不區(qū)分大小寫
var pattern2 = /[bc]at/i;
//匹配所有以“at”結(jié)尾的3個(gè)字符的組合辱挥,不區(qū)分大小寫
var pattern3 = /.at/gi;

與其他元字符在正則表達(dá)式中都有一或多種特殊用途犁嗅,因此如果想要匹配字符串中包含的這些字符,就必須對(duì)它們進(jìn)行轉(zhuǎn)義晤碘。

另一種創(chuàng)建正則表達(dá)式的方式是使用RegExp構(gòu)造函數(shù)褂微,它接收兩個(gè)參數(shù):一個(gè)是要匹配的字符串模式功蜓,另一個(gè)是可選的標(biāo)志字符串。

var pattern1 = /[bc]at/i;

var pattern2 = new RegExp("[bc]at", "i");

要注意的是宠蚂,傳遞給RegExp構(gòu)造函數(shù)的兩個(gè)參數(shù)都是字符串式撼。在某些情況下要對(duì)字符進(jìn)行雙重轉(zhuǎn)義。所有元字符都必須雙重轉(zhuǎn)義求厕,那些已經(jīng)轉(zhuǎn)義的字符也是如此著隆,例如\n(字符\在字符串中通常被轉(zhuǎn)義為\,而在正則表達(dá)式字符串中就會(huì)變成\\)呀癣。下表給出了一些模式美浦。

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

使用正則表達(dá)式字面量和使用RegExp構(gòu)造函數(shù)創(chuàng)建的表達(dá)式不一樣。
ECMAScript 5 明確規(guī)定项栏,使用正則表達(dá)式字面量必須像直接調(diào)用RegExp構(gòu)造函數(shù)一樣浦辨,每次都創(chuàng)建新的RegExp實(shí)例。IE9+沼沈、Firefox 4+ 和 Chrome 都據(jù)此做出了修改荤牍。

5.4.1 RegExp 實(shí)例屬性

RegExp的每個(gè)實(shí)例都具有下列屬性,通過(guò)這些屬性可以取得有關(guān)模式的各種信息庆冕。

  • global:布爾值,表示是否設(shè)置了g標(biāo)志劈榨。
  • ignoreCase:布爾值访递,表示是否設(shè)置了i標(biāo)志伦意。
  • lastIndex:整數(shù)汽煮,表示開(kāi)始搜索下一個(gè)匹配項(xiàng)的字符位置,從0算起缴淋。
  • multiline:布爾值旱函,表示是否設(shè)置了m標(biāo)志响巢。
  • source:正則表達(dá)式的字符串表示,按照字面量形式而非傳入構(gòu)造函數(shù)中的字符串模式返回棒妨。

5.4.2 RegExp 實(shí)例方法

RegExp對(duì)象的主要方法是exec()踪古。exec()接受一個(gè)參數(shù),即要應(yīng)用模式的字符串券腔,然后返回包含第一個(gè)匹配項(xiàng)信息點(diǎn)數(shù)組伏穆;或者在沒(méi)有匹配項(xiàng)的情況下返回null。返回的數(shù)組雖然是Array的實(shí)例纷纫,但包含倆額外的屬性:indexinput枕扫。其中,index表示匹配在字符串中的位置辱魁,而input表示應(yīng)用正則表達(dá)式的字符串烟瞧。在數(shù)組中诗鸭,第一項(xiàng)是與整個(gè)模式匹配的字符串,其他項(xiàng)是與模式中的捕獲組匹配的字符串(如果模式中沒(méi)有捕獲組参滴,則該數(shù)組只包含一項(xiàng))强岸。

var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;

var matches = pattern.exec(text);
alert(matches.index);  //0
alert(matches.input);  //"mom and dad and baby"
alert(matches[0]);  //"mom and dad and baby"
alert(matches[1]);  //" and dad and baby"
alert(matches[2]);  //" and baby"

對(duì)于exec()方法而言,即使在模式中設(shè)置了全局標(biāo)志(g),他每次也只會(huì)返回一個(gè)一個(gè)匹配項(xiàng)卵洗。在設(shè)置全局標(biāo)志的情況下请唱,每次調(diào)用exec()則都會(huì)在字符串中繼續(xù)查找新匹配項(xiàng),如下面的例子所示过蹂。

正則表達(dá)式的第二個(gè)方法是test()十绑,它接受一個(gè)字符串參數(shù)。在模式與該參數(shù)匹配的情況下返回true酷勺;否則本橙,返回false
RegExp實(shí)例繼承的toLocaleString()toString()方法都會(huì)返回正則表達(dá)式的字面量脆诉,于創(chuàng)建方式無(wú)關(guān)甚亭。

5.4.3 RegExp 構(gòu)造函數(shù)屬性

具體屬性略。
還有多達(dá)9個(gè)用于存儲(chǔ)捕獲組的構(gòu)造函數(shù)屬性击胜。訪問(wèn)這些屬性的語(yǔ)法是RegExp.$1亏狰、RegExp.$2...RegExp.$9, 分別用于存儲(chǔ)第一,第二......第九個(gè)匹配的捕獲組偶摔。在調(diào)用exec()test()方法時(shí)暇唾,這些屬性會(huì)被自動(dòng)填充。

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

if(pattern.test(text)) {
  alert(RegExp.$1);  //sh
  alert(RegExp.$2);  //t
}

5.4.4 模式的局限性

下面列出了 ECMAScript 正則表達(dá)式不支持的特性辰斋。

  • 匹配字符串開(kāi)始和結(jié)尾的\A 和 \Z (但支持以插入符號(hào)^和美元符號(hào)$來(lái)匹配字符串的開(kāi)始和結(jié)尾)
  • 向后查找(但完全支持向前查找)
  • 并集和交集類
  • 原子組
  • Unicode 支持
  • 命名的捕獲組(但支持編號(hào)的捕獲組)
  • s(單行)和 x(無(wú)間隔)匹配模式
  • 條件匹配
  • 正則表達(dá)式注釋

5.5 Function 類型

每個(gè)函數(shù)都是Function類型的實(shí)例策州,而且都與其他引用類型一樣具有屬性和方法。由于函數(shù)是對(duì)象宫仗,因此函數(shù)名實(shí)際上也是一個(gè)指向函數(shù)對(duì)象的指針够挂,不會(huì)與某個(gè)函數(shù)綁定。函數(shù)通常是使用函數(shù)聲明語(yǔ)法定義的藕夫。

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

這與下面使用函數(shù)表達(dá)式定義函數(shù)的方式幾乎相差無(wú)幾

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

最后一種定義函數(shù)的方式是使用Function構(gòu)造函數(shù)孽糖,不推薦。

由于函數(shù)名僅僅是指向函數(shù)的指針毅贮,因此函數(shù)名與包含對(duì)象指針的其他變量沒(méi)有什么不同梭姓。

function sum(num1, num2) {
  return num1 + num2;
}
alert(sum(10, 10));  //20

var anotherSum = sum;
alert(anotherSum(10, 10));  //20

sum = null;
alert(anotherSum(10, 10));  //20

5.5.1 沒(méi)有重載(深入理解)

將函數(shù)名想象為指針,也有助于理解為什么 ECMAScript 中沒(méi)有函數(shù)重載的概念嫩码。

5.5.2 函數(shù)聲明與函數(shù)表達(dá)式

解析器會(huì)率先讀取函數(shù)聲明誉尖,并使其在執(zhí)行任何代碼之前可用(可以訪問(wèn));至于函數(shù)表達(dá)式铸题,則必須等到解析器執(zhí)行到它所在的代碼行铡恕,才會(huì)真正被解釋執(zhí)行琢感。

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

以上代碼正常運(yùn)行。因?yàn)樵诖a執(zhí)行之前探熔,解析器就已經(jīng)通過(guò)一個(gè)名為函數(shù)聲明提升的過(guò)程驹针,讀取并將函數(shù)聲明添加到執(zhí)行環(huán)境中。

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

以上代碼在運(yùn)行期間會(huì)產(chǎn)生錯(cuò)誤诀艰,原因在于函數(shù)位于一個(gè)初始化語(yǔ)句中柬甥,而不是一個(gè)函數(shù)聲明。

作為值的函數(shù)

因?yàn)?ECMAScript 中的函數(shù)本身就是變量其垄,所以函數(shù)也可以作為值來(lái)使用苛蒲。不僅可以像傳遞參數(shù)一樣把一個(gè)函數(shù)傳遞給另一個(gè)函數(shù),而且可以將一個(gè)函數(shù)作為另一個(gè)函數(shù)的結(jié)果返回绿满。

function callSomeFunction(someFunction, someArgument) {
  return someFunction(someArgument);
}
function add10(num) {
  return num + 10;
}

var result = callSomeFunction(add10, 10);
alert(result);  //20

當(dāng)然臂外,可以從一個(gè)函數(shù)中返回另一個(gè)函數(shù),而且這也是極為有用的一種技術(shù)喇颁。

function createComparisonFunction(propertyName) {
  return function(object1, object2) {
    var value1 = object1[propertyName];
    var value2 = object2[propertyName];
    
    if (value1 < value2) {return -1;} else if (value1 > value2) {return1;} else  {return 0'}
  };
}
var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];
data.sort(createComparisonFunction("name"));
alert(data[0].name);  //Nicholas
data.sort(createComparisonFunction("age"));
alert(data[0].name);  //Zachary

5.5.4 函數(shù)內(nèi)部屬性

在函數(shù)內(nèi)容中漏健,有兩個(gè)特殊的對(duì)象:argumentsthis。其中橘霎,arguments()是一個(gè)類數(shù)組對(duì)象蔫浆,包含著傳入函數(shù)中的所有參數(shù)。雖然arguments的主要用途是保存函數(shù)參數(shù)姐叁,但這個(gè)對(duì)象還有一個(gè)名叫callee的屬性瓦盛,該屬性是一個(gè)指針,指向擁有這個(gè)arguments對(duì)象的函數(shù)七蜘。

function factorial (num) {
  if (num <=1) {
    return 1;
  } else {
    return num * factorial(num-1)
  }
}

定義階乘函數(shù)一般都要用到遞歸算法;問(wèn)題是這個(gè)函數(shù)的執(zhí)行與函數(shù)名factorial緊緊耦合在了一起墙懂。為了消除這種耦合現(xiàn)象橡卤,可以這樣使用arguments.callee

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

在重寫后的factorial()函數(shù)的函數(shù)體內(nèi)损搬,沒(méi)有在引用函數(shù)名factorial碧库。這樣,無(wú)論引用函數(shù)時(shí)使用的是什么名字巧勤,都可以保證正常完成遞歸調(diào)用嵌灰。

var trueFactorial = factorial;

factorial = function () {
  return 0;
};
alert(trueFactorial(5));  //120
alert(factorial(5));  //0

函數(shù)內(nèi)部的另一個(gè)特殊對(duì)象是this,引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象——或者可以說(shuō)是this值(擋在網(wǎng)頁(yè)的全局作用域中調(diào)用函數(shù)時(shí),this對(duì)象引用的就是window)颅悉。

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

function sayColor () {
  alert(this.color);
}
sayColor();  //"red"
o.syaColor = sayColor;
o.sayColor();  //"blue"

請(qǐng)牢記沽瞭,函數(shù)的名字僅僅是一個(gè)包含指針的變量而已。因此剩瓶,即使是在不同的環(huán)境中執(zhí)行驹溃,全局的sayColor()函數(shù)與o.sayColor()指向的仍然是同一個(gè)函數(shù)城丧。

ECMAScript 5 也規(guī)范化了另一個(gè)函數(shù)對(duì)象的屬性:caller。這個(gè)屬性中保存著調(diào)用當(dāng)前函數(shù)的函數(shù)的引用豌鹤,如果是在全局作用域中調(diào)用當(dāng)前函數(shù)亡哄,它的值為null

function outer() {
  inner();
}
function inner() {
  alert(inner.caller);
}
outer();

以上代碼會(huì)導(dǎo)致警告框中顯示outer()函數(shù)的源代碼布疙。因?yàn)?code>outer()調(diào)用了inner()蚊惯,所以inner.caller就指向outer()。為了實(shí)現(xiàn)更松散的耦合灵临,也可以通過(guò)arguments.callee.caller來(lái)訪問(wèn)相同的信息截型。

嚴(yán)格模式下,arguments.callee會(huì)導(dǎo)致錯(cuò)誤俱诸。

5.5.5 函數(shù)屬性和方法

ECMAScript 中的函數(shù)是對(duì)象菠劝,因此函數(shù)也有屬性和方法。每個(gè)函數(shù)包含兩個(gè)屬性:lengthprototype睁搭。其中赶诊,length屬性表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)。

function sayName(name) {
  alert(name);
}
function sum(num1, num2) {
  return num1 + num2;
}
function sayHi() {
  alert("hi");
}

alert(sayName.length);  //1
alert(sum.length);  //2
alert(sayHi.length);  //0

對(duì)于ECMAScript 中的引用類型而言园骆,prototype是保存它們所有實(shí)例方法的真正所在舔痪。換句話說(shuō),諸如toString()valueOf()等方法實(shí)際上都保持在prototype名下锌唾,只不過(guò)是通過(guò)各自對(duì)象的實(shí)例訪問(wèn)罷了锄码。在創(chuàng)建自定義引用類型以及實(shí)現(xiàn)繼承時(shí),prototype屬性的作用是極為重要的晌涕。
每個(gè)函數(shù)都包含兩個(gè)非繼承而來(lái)的方法:apply()call()滋捶。這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù)。實(shí)際上等于設(shè)置函數(shù)體內(nèi)this對(duì)象的值余黎。首先重窟,apply()方法接收兩個(gè)參數(shù):一個(gè)是在其中運(yùn)行函數(shù)的作用域,另一個(gè)是參數(shù)數(shù)組惧财。其中巡扇,第二個(gè)參數(shù)可以是Array的實(shí)例,也可以是arguments對(duì)象垮衷。

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

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

function callSum2(num1, num2) {
  return sum.apply(this, [num1, num2]);  //傳入?yún)?shù)
}

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

callSum1()在執(zhí)行sum()函數(shù)時(shí)傳入了this作為this值(因?yàn)槭窃谌肿饔糜蛑姓{(diào)用的厅翔,所以傳入的就是window對(duì)象)和arguments對(duì)象。而callSum2同樣也調(diào)用了sum()函數(shù)搀突,但它傳入的則是this和一個(gè)參數(shù)數(shù)組刀闷。這兩個(gè)函數(shù)都會(huì)正常執(zhí)行并返回正確的結(jié)果。

在嚴(yán)格模式下,未指定環(huán)境對(duì)象而調(diào)用函數(shù)涩赢,則this值不會(huì)轉(zhuǎn)型為window戈次。除非明確把函數(shù)添加到某個(gè)對(duì)象或者調(diào)用apply()call(),否則this值將是undefined筒扒。

call()方法與apply()方法的作用相同怯邪,它們的區(qū)別僅在于接收參數(shù)的方式不同。對(duì)于call()方法而言花墩,第一個(gè)參數(shù)是this值沒(méi)有變化悬秉,變化的是其余參數(shù)都直接傳遞給函數(shù)。即在使用call()方法時(shí)冰蘑,傳遞給函數(shù)的參數(shù)必須逐個(gè)列舉出來(lái)和泌。

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

function callSum(num1, num2) {
  return sum.call(this, num1, num2);
}

alert(callSum(10,10));  //20

傳遞參數(shù)并非apply()call()真正的用武之地;它們真正強(qiáng)大的地方是能夠擴(kuò)充函數(shù)賴以運(yùn)行的作用域祠肥。

window. 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

使用call()apply來(lái)擴(kuò)充作用域的最大好處武氓,就是對(duì)象不需要與方法有任何耦合關(guān)系。
ECMAScript 5 還定義了一個(gè)方法:bind()仇箱。這個(gè)方法會(huì)創(chuàng)建一個(gè)函數(shù)的實(shí)例县恕,其this值會(huì)被綁定到傳給bind()函數(shù)的值。

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

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

每個(gè)函數(shù)繼承的toLocaleString()toString()方法始終都返回函數(shù)的代碼剂桥。返回代碼的格式則因?yàn)g覽器而異——有的返回的代碼與源代碼中的函數(shù)代碼一樣忠烛,而有的則返回函數(shù)代碼的內(nèi)部表示,即由解析器刪除了注釋并對(duì)某些代碼作了改動(dòng)后的代碼权逗。由于存在這些差異美尸,我們無(wú)法根據(jù)這兩個(gè)方法返回的結(jié)果來(lái)實(shí)現(xiàn)任何重要功能;不過(guò)斟薇,這些信息在調(diào)試代碼時(shí)倒是很有用师坎。另外一個(gè)繼承的valueOf()方法同樣也只有返回函數(shù)代碼。

5.6 基本包裝類型

為了便于操作基本類型值堪滨,ECMAScript 還提供了 3 個(gè)特殊的引用類型:Boolean,NumberString胯陋。這些類型與本章介紹的其他引用類型相似,但同時(shí)也具有與各自的基本類型相應(yīng)的特殊行為椿猎。實(shí)際上惶岭,每當(dāng)讀取一個(gè)基本類型值的時(shí)候寿弱,后臺(tái)就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的基本包裝類型的對(duì)象犯眠,從而讓我們能夠調(diào)用一些方法來(lái)操作這些數(shù)據(jù)。

var s1 = "some text";
var s2 = s1.substring(2);

俺們知道症革,基本類型值不是對(duì)象筐咧,因而從邏輯上講它們不應(yīng)該有方法(盡管如我們所愿,它們確實(shí)有方法)。其實(shí)量蕊,為了讓我們實(shí)現(xiàn)這種直觀的操作铺罢,后臺(tái)已經(jīng)自動(dòng)完成了一系列的處理。當(dāng)?shù)诙写a訪問(wèn) s1 時(shí)残炮,訪問(wèn)過(guò)程處于一種讀取模式韭赘,也就是要從內(nèi)存中讀取這個(gè)字符串的值。而在讀取模式中訪問(wèn)字符串時(shí)势就,后臺(tái)都會(huì)自動(dòng)完成下列處理泉瞻。

  1. 創(chuàng)建String類型的一個(gè)實(shí)例;
  2. 在實(shí)例上調(diào)用指定的方法苞冯;
  3. 銷毀這個(gè)實(shí)例袖牙。

可以將以上三個(gè)步驟想象成是執(zhí)行了下列ECMAScript代碼。

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;

經(jīng)過(guò)此番處理舅锄,基本的字符串值就變得跟對(duì)象一樣了鞭达。而且,上面這三個(gè)步驟也分別適用于BooleanNumber類型對(duì)應(yīng)的布爾值和數(shù)字值皇忿。
引用類型與基本包裝類型的主要區(qū)別就是對(duì)象的生存期畴蹭。使用new操作符創(chuàng)建的引用類型的實(shí)例,在執(zhí)行流離開(kāi)當(dāng)前作用域之前都一直保存在內(nèi)存中禁添。而自動(dòng)創(chuàng)建的基本包裝類型的對(duì)象撮胧,則只存在于一行代碼的執(zhí)行瞬間,然后立即銷毀老翘。這意味著我們不能在運(yùn)行時(shí)為基本類型添加屬性和方法芹啥。

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

問(wèn)題的原因在于第二行創(chuàng)建的String對(duì)象在執(zhí)行第三行代碼時(shí)已經(jīng)被銷毀了。第三行代碼又創(chuàng)建自己的String對(duì)象铺峭,而該對(duì)象沒(méi)有color屬性墓怀。
當(dāng)然,可以顯示地調(diào)用Boolean卫键、Number傀履、String來(lái)創(chuàng)建基本包裝類型的對(duì)象。應(yīng)該盡量避免這樣做莉炉,因?yàn)檫@種方法做很容易讓人分不清自己是在處理基本類型還是引用類型的值钓账。對(duì)基本包裝類型的實(shí)例調(diào)用typeof會(huì)返回object,而且所有基本包裝類型的對(duì)象都會(huì)被轉(zhuǎn)換為布爾值true
Object構(gòu)造函數(shù)也會(huì)像工廠方法一樣絮宁,根據(jù)傳入值的類型返回相應(yīng)基本包裝類型的實(shí)例梆暮。

var obj = new Object("some text");
alert(obj instanceof String);  //true

把字符串傳給Object構(gòu)造函數(shù),就會(huì)創(chuàng)建String的實(shí)例绍昂;其他類似啦粹。
要注意的是偿荷,使用new調(diào)用基本包裝類型的構(gòu)造函數(shù),與直接調(diào)用同名的轉(zhuǎn)型函數(shù)是不一樣的唠椭。

var value = "25";
var number = Number(value);  //轉(zhuǎn)型函數(shù)
alert(typeof number);  //"number"

var obj = new Number(value);  //構(gòu)造函數(shù)
alert(typeof obj);  //"object"

5.6.1 Boolean 類型

Boolean類型是與布爾值對(duì)應(yīng)的引用類型跳纳。

var booleanObject = new Boolean(true);

Boolean類型的實(shí)例重寫了valueOf()方法,返回基本類型值truefalse;重寫了toString()方法贪嫂,返回字符串“true”和“false”寺庄。用處不大,經(jīng)常造成誤解力崇。其中最常見(jiàn)的問(wèn)題是在布爾表達(dá)式中使用Boolean對(duì)象铣揉。

var falseObject = new Boolean(false);
var result = falseObject && true;
alert(result);  //true

var falseValue = false;
result = falseValue && true;
alert(result);  //false

在布爾運(yùn)算中,false && true等于false餐曹。但是布爾表達(dá)式中的所有對(duì)象都會(huì)被轉(zhuǎn)換為true逛拱,因此falseObject對(duì)象在布爾表達(dá)式中代表的是true
基本類型與引用類型的布爾值還有兩個(gè)區(qū)別台猴。首先朽合,typeof操作符對(duì)基本類型返回"boolean",而對(duì)引用類型返回"object"饱狂。其次曹步,由于Boolean對(duì)象是Boolean類型的實(shí)例,所以使用instanceof操作符測(cè)試Boolean對(duì)象會(huì)返回true休讳,而測(cè)試基本類型的布爾值則返回false讲婚。

alert(typeof falseObject);  //object
alert(typeof falseValue);  //boolean
alert(falseObject instanceof Boolean);  //true
alert(falseValue instanceof Boolean);  //false

建議永遠(yuǎn)不要使用Boolean對(duì)象

5.6.2 Number 類型

Number是與數(shù)字值對(duì)應(yīng)的引用類型。要?jiǎng)?chuàng)建Number對(duì)象俊柔,可以在調(diào)用Number構(gòu)造函數(shù)時(shí)向其中傳遞相應(yīng)的數(shù)值筹麸。

var numberObject = new Number(10);

Number類型也重寫了valueOf()toLocaleString()toString()方法雏婶。重寫后的valueOf()方法返回對(duì)象表示的基本類型的數(shù)值物赶,另外兩個(gè)方法則返回字符串形式的數(shù)值。在第 3 章中介紹過(guò)留晚,可以為toString()方法傳遞一個(gè)表示基數(shù)的參數(shù)酵紫,告訴它返回幾進(jìn)制的字符串形式。

除了繼承的方法外错维,Number類型還提供了一些用于將數(shù)值格式化為字符串的方法奖地。其中,toFixed()方法會(huì)按照指定的小數(shù)位返回?cái)?shù)值的字符串表示赋焕。

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

如果數(shù)值本身包含的小數(shù)位比指定的還多参歹,那么接近的最大小數(shù)位的值就會(huì)舍入。

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

另外可用于格式化數(shù)值的方法是toExponential()宏邮,該方法返回以指數(shù)表示法(也稱 e 表示法)表示的數(shù)值的字符串形式泽示。,接受一個(gè)參數(shù)蜜氨,同樣也是指定輸出結(jié)果中的小數(shù)位數(shù)械筛。

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

如果你想得到表示某個(gè)數(shù)值的最合適的格式,就應(yīng)該使用toPrecision()方法飒炎。
對(duì)于一個(gè)數(shù)值來(lái)說(shuō)埋哟,toPrecision()方法可能會(huì)返回固定大小 (fixed)格式,也可能返回指數(shù)(exponential)格式郎汪;具體規(guī)則是看哪種格式最合適赤赊。該方法接收一個(gè)參數(shù),即表示數(shù)值的所有數(shù)字的位數(shù)(不包括指數(shù)部分)煞赢。

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

不建議直接實(shí)例化Number類型抛计,其他與Boolean對(duì)象一樣。

5.6.3 String 類型

String類型是字符串的對(duì)象包裝類型照筑,可以像下面這樣使用String構(gòu)造函數(shù)來(lái)構(gòu)造吹截。

var stringObject = new String("hello world");

String對(duì)象的方法也可以在所有基本的字符串值中訪問(wèn)到。其中凝危,繼承的valueOf()波俄,toLocaleString()toString()方法,都返回對(duì)象所表示的基本字符串值蛾默。
String類型的每個(gè)實(shí)例都有一個(gè)length屬性懦铺,表示字符串中包含多個(gè)字符。

var stringValue = "hello world";
alert(stringValue.length);  //11

即使字符串中包含雙字節(jié)字符(不是占一個(gè)字節(jié)的 ASCII 字符)支鸡,每個(gè)字符也仍然算一個(gè)字符冬念。

  1. 字符方法
    兩個(gè)用于訪問(wèn)字符串中特定字符的方法是:charAt()charCodeAt()。這倆方法都接收一個(gè)參數(shù)牧挣,即基于0的字符位置刘急。其中,charAt()方法以單字符字符串的形式返回給定位置的那個(gè)字符浸踩。
var stringValue = "hello world";
alert (stringValue.charAt(1));  //"e"

如果你想得到的不是字符而是字符編碼叔汁。

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

在支持的瀏覽器中,可以使用方括號(hào)加數(shù)字索引來(lái)訪問(wèn)字符串中的特定字符检碗。

var stringValue = "hello world";
alert(stringValue[1]);  //"e"
  1. 字符串操作方法
    concat()用于將一個(gè)或多個(gè)字符串拼接起來(lái)据块,返回拼接得到的新字符串。
var stringValue = "hello";
var result = stringValue.concat(" world");
alert(result);  //"hello world"
alert(stringValue);  //"hello"

concat方法可以接收任意多個(gè)參數(shù)折剃,也就是說(shuō)另假,可以通過(guò)它拼接任意多個(gè)字符串。

var stringValue = "hello";
var result = stringValue.concat(" world", "!");
alert(result);  //"hello world!"
alert(stringValue);  //"hello"

雖然concat()是專門用來(lái)拼接字符串的方法怕犁,但實(shí)踐中使用更多的還是加號(hào)操作符(+)边篮。
ECMAScript 提供了三個(gè)基于子字符串創(chuàng)建新字符串的方法:slice()己莺、substr()substring()。這三個(gè)方法都會(huì)返回被操作字符串的一個(gè)子字符串戈轿,而且也都接受一或兩個(gè)參數(shù)凌受。第一個(gè)參數(shù)指定子字符串的開(kāi)始位置,第二個(gè)參數(shù)(在指定的情況下)表示子字符串到哪里結(jié)束思杯。具體來(lái)說(shuō)胜蛉,slice()substring()的第二個(gè)參數(shù)指定的是字符串最后一個(gè)字符后面的位置。而substr()的第二個(gè)參數(shù)指定的則是返回的字符個(gè)數(shù)色乾。如果沒(méi)有傳遞第二個(gè)參數(shù)誊册,則將字符串的長(zhǎng)度作為結(jié)束位置。這些方法同樣也不會(huì)修改字符串本身的值暖璧。

var s = "hello world";
alert(s.slice(3));  //"lo world"
alert(s.substring(3));  //"lo world"
alert(s.substr(3));  //"lo world"
alert(s.slice(3, 7));  //"lo w"
alert(s.substring(3, 7));  //"lo w"
alert(s.substr(3, 7));  //"lo worl"

在傳遞給這些方法的參數(shù)是負(fù)值的情況下案怯,它們的行為就不盡相同了。其中澎办,slice()方法會(huì)將傳入的負(fù)值與字符串的長(zhǎng)度相加殴泰,substr()方法會(huì)將負(fù)的第一個(gè)參數(shù)加上字符串的長(zhǎng)度,而將負(fù)的第二個(gè)參數(shù)轉(zhuǎn)換為 0浮驳。最后悍汛,substring()方法會(huì)把所有負(fù)值參數(shù)都轉(zhuǎn)換為 0。substring()方法會(huì)將較小的數(shù)作為開(kāi)始位置至会,將較大的數(shù)作為結(jié)束位置离咐。

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

IE 的 JavaScript 實(shí)現(xiàn)在處理向 substr()方法傳遞負(fù)值的情況時(shí)存在問(wèn)題,它會(huì)返回原始的字符串奉件。IE9 修復(fù)了這個(gè)問(wèn)題宵蛀。

  1. 字符串位置方法
    由兩個(gè)可以從字符串中查找子字符串的方法:indexOf()lastIndexOf()。這兩個(gè)方法都是從一個(gè)字符串中搜索給定的子字符串县貌,然后返回子字符串的位置(如果沒(méi)有找到术陶,則返回 -1)。這倆方法區(qū)別在于:indexOf()方法從字符串的開(kāi)頭向后搜索子字符串煤痕,而lastIndexOf()方法是從字符串的末尾向前搜索子字符串梧宫。
var s = "hello world";
alert(s.indexOf("o"));  //4
alert(s.lastIndexOf("o"));  //7

這倆方法接收可選的第二個(gè)參數(shù),表示從字符串中的那個(gè)位置開(kāi)始搜索摆碉。indexOf()會(huì)從該參數(shù)指定的位置向后搜索塘匣,忽略該位置之前的所有字符;而lastIndexOf()則會(huì)從指定的位置向前搜索巷帝,忽略該位置之后的所有字符忌卤。

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

在使用第二個(gè)參數(shù)的情況下,可以通過(guò)循環(huán)調(diào)用indexOf()lastIndexOf()來(lái)找到所有匹配的子字符串楞泼。

var s = "asjfjsjf;sjfjsdfjsdljfsafjsaf";
var position = new Array();
var pos = s.indexOf("a");
while (pos > -1) {
  positions.push(pos);
  pos = s.indexOf("a", pos + 1);
}
alert(positions);
  1. trim() 方法
    這個(gè)方法會(huì)創(chuàng)建一個(gè)字符串的副本驰徊,刪除前置及后綴的所有空格笤闯,然后返回結(jié)果。
var s = "  hello world "
var trimmed = s.trim();
alert(s);  //"  hello world "
alert(trimmed);  //"hello world"

先進(jìn)瀏覽器還支持非標(biāo)準(zhǔn)的trimLeft()trimRight()方法棍厂,分別用于刪除字符串開(kāi)頭和末尾的空格颗味。

  1. 字符串大小寫轉(zhuǎn)換方法
    ECMAScript 中涉及字符串大小寫轉(zhuǎn)換的方法有 4 個(gè):toLowerCase()toLocaleLowerCase()勋桶、toUpperCase()toLocaleUpperCase()侥猬。

  2. 字符串的模式匹配方法
    第一個(gè)方法就是match()例驹,在字符串上調(diào)用這個(gè)方法,本質(zhì)上與調(diào)用RegExpexec()方法相同退唠。match()方法只接受一個(gè)參數(shù)鹃锈,要么是一個(gè)正則表達(dá)式,要么是一個(gè)RegExp對(duì)象瞧预。

var text = "cat, bat, sat, fat";
var pattern = /.at/;
var matches = text.match(pattern);
alert(matches.index);  //0  
alert(matches[0]);  //"cat"
alert(pattern.lastIndex);  //0

另一個(gè)用于查找模式的方法是search()屎债。這個(gè)方法的唯一參數(shù)與match()方法的參數(shù)相同:由字符串或RegExp對(duì)象指定的一個(gè)正則表達(dá)式。search()方法返回字符串中第一個(gè)匹配項(xiàng)的索引垢油;如果沒(méi)有找到匹配項(xiàng)盆驹,則返回 -1。而且滩愁,search()方法始終是從字符串開(kāi)頭向后查找模式躯喇。

var text = "cat, bat, sat, fat";
var pos = text.search(/at/);
alert(pos);  //1

為了簡(jiǎn)化替換子字符串的操作,ECMAScript 提供了replace()方法硝枉。這個(gè)方法接受兩個(gè)參數(shù):第一個(gè)參數(shù)可以是一個(gè)RegExp對(duì)象或者一個(gè)字符串(這個(gè)字符串不會(huì)被轉(zhuǎn)換成正則表達(dá)式)廉丽,第二個(gè)參數(shù)可以是一個(gè)字符串或者一個(gè)函數(shù)。如果第一個(gè)參數(shù)是字符串妻味,那么只會(huì)替換第一個(gè)字符串正压,要想替換所有子字符串,唯一的辦法就是提供一個(gè)正則表達(dá)式责球,而且要指定全局標(biāo)志焦履。

var text = "cat, bat, sat, fat";
var result = text.replace("at", "ond");
alert(result);  //"cound, bat, sat, fat"
result = text.replace(/at/g, "ond");
alert(result);  //"cond, bond, aond, fond"

replace()方法的第二個(gè)參數(shù)也可以是一個(gè)函數(shù)。在只有一個(gè)匹配項(xiàng)的的情況下雏逾,會(huì)向這個(gè)函數(shù)傳遞 3 個(gè)參數(shù):模式的匹配項(xiàng)裁良,模式匹配項(xiàng)在字符串中的位置和原始字符串。在正則表達(dá)式中定義了多個(gè)捕獲組的情況下校套,傳遞給函數(shù)的參數(shù)依次是模式的匹配項(xiàng)价脾,第一個(gè)捕獲組的匹配項(xiàng),第二個(gè)捕獲組的匹配項(xiàng)笛匙。侨把。犀变。,但最后兩個(gè)參數(shù)仍然分別是模式的匹配項(xiàng)在字符串中的位置和原始字符串秋柄。這個(gè)函數(shù)應(yīng)該返回一個(gè)字符串贱纠,表示應(yīng)該被替換額匹配項(xiàng)使用函數(shù)作為replace()方法的第二個(gè)參數(shù)可以實(shí)現(xiàn)更加精細(xì)的替換操作

function htmlEscape(text) {    return text.replace(/[<>"&]/g, function(match,pos,originalText) {        switch(match) {            case "<":                return "<";            case ">":                return ">";            case "&":                return "&";            case "\*":                return """;        }    });}

最后一個(gè)與模式匹配有關(guān)的方法是split()坑填,這個(gè)方法可以基于指定的分隔符將一個(gè)字符串分割成多個(gè)子字符串,并將結(jié)果放在一個(gè)數(shù)組中。分隔符可以是字符串呐馆,也可以是一個(gè)RegExp對(duì)象。split()方法可以接受可選的第二個(gè)參數(shù)魔慷,用于指定數(shù)組的大小丙笋,以確保返回的數(shù)組不會(huì)超過(guò)既定大小。

var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(",");  //["red","blue","green", "yellow"]
var colors2 = colorText.split(",", 2);  //["red", "blue"]
var colors3 = colorsText.split(/[^\,]+/);  //["", ",", ",",",", ""] 
  1. localeCompare() 方法
    與操作字符串有關(guān)的最后一個(gè)方法是localeCompare()芦劣,這個(gè)方法比較兩個(gè)字符串粗俱,并返回下列值中的一個(gè):
  • 如果字符串在字母表中應(yīng)該排在字符串參數(shù)之前,則返回一個(gè)負(fù)數(shù)(大多數(shù)情況下是 -1虚吟, 具體的值要視實(shí)現(xiàn)而定)寸认;
  • 如果字符串等于字符串參數(shù),則返回 0串慰;
  • 如果字符串在字母表中應(yīng)該排在字符串參數(shù)之后偏塞,則返回一個(gè)正數(shù)(大多數(shù)情況下是 1,具體的值同樣要視實(shí)現(xiàn)而定)邦鲫。
var s = "yellow";
alert(s.localeCompare("brick"));  //1
alert(s.localeCompare("yellow"));  //0
alert(s.localeCompare("zoo"));  //-1

最好采用函數(shù)判斷并規(guī)定返回?cái)?shù)值烛愧。

  1. fromCharCode() 方法
    String構(gòu)造函數(shù)本身還有一個(gè)靜態(tài)方法:fromCharCode()。這個(gè)方法的任務(wù)是接收一或多個(gè)字符編碼掂碱,然后將他們轉(zhuǎn)換成一個(gè)字符串怜姿。從本質(zhì)上看,這個(gè)方法與實(shí)例方法charCodeAt()執(zhí)行的是相反的操作疼燥。
alert(String.fromCharCode(104, 101, 108, 108, 111));  //"hello"
  1. HTML 方法
    盡量不使用這些方法沧卢。故不列出。

5.7 單體內(nèi)置對(duì)象

5.7.1 Global 對(duì)象

不屬于任何其他對(duì)象的屬性和方法醉者,最終都是它的屬性和方法但狭。

  1. URI 編碼方法
    encodeURI()encodeURIComponent()方法可以對(duì) URI 進(jìn)行編碼,以便發(fā)送給瀏覽器撬即。有效的 URI 中不能包含某些字符立磁,例如空格。
    其中剥槐,encodeURI()主要用于整個(gè)URI(例如唱歧,http://www.baidu.com/illegal value.htm),而encodeURIComponent()主要用于對(duì)某一段(例如illegal value.htm)進(jìn)行編碼。它們的主要區(qū)別在于颅崩,encodeURI()不會(huì)對(duì)本身屬于 URI 的特殊字符進(jìn)行編碼几于,例如冒號(hào),正斜杠沿后,問(wèn)號(hào)和井字號(hào)沿彭;而encodeURIComponent()則會(huì)對(duì)它發(fā)現(xiàn)的任何非標(biāo)準(zhǔn)字符進(jìn)行編碼。
    對(duì)應(yīng)的方法為decodeURI()decodeURIComponent()尖滚。

一般來(lái)說(shuō)喉刘,使用encodeURIComponent()方法更多,因?yàn)樵趯?shí)踐中更常見(jiàn)的是對(duì)查詢字符串參數(shù)而不是對(duì)基礎(chǔ) URI 進(jìn)行編碼漆弄。

  1. eval() 方法
    非常危險(xiǎn)睦裳,略。
  2. Global 對(duì)象的屬性
    下表列出了所有屬性
屬性 說(shuō)明
undefined 特殊值
NaN 特殊值
Infinity 特殊值
Object 構(gòu)造函數(shù)
Array 構(gòu)造函數(shù)
Function 構(gòu)造函數(shù)
Boolean 構(gòu)造函數(shù)
String 構(gòu)造函數(shù)
Number 構(gòu)造函數(shù)
Date 構(gòu)造函數(shù)
RegExp 構(gòu)造函數(shù)
Error 構(gòu)造函數(shù)
EvalError 構(gòu)造函數(shù)
RangeError 構(gòu)造函數(shù)
ReferenceError 構(gòu)造函數(shù)
SyntaxError 構(gòu)造函數(shù)
TypeError 構(gòu)造函數(shù)
URIError 構(gòu)造函數(shù)
  1. window 對(duì)象
    ECMAScript 雖然沒(méi)有指出如何直接訪問(wèn)Global對(duì)象置逻,但Web瀏覽器都是將這個(gè)全局對(duì)象作為window對(duì)象的一部分加以實(shí)現(xiàn)的推沸。因此备绽,在全局作用域中聲明的所有變量和函數(shù)券坞,就都成為了widnow對(duì)象的屬性。

5.7.2 Math 對(duì)象

Math對(duì)象提供了輔助完成數(shù)學(xué)計(jì)算的屬性和方法肺素。
1.Math 對(duì)象的屬性

屬性 說(shuō)明
Math.E 自然對(duì)數(shù)的底數(shù)恨锚,即常量e的值
Math.LN10 10的自然對(duì)數(shù)
Math.LN2 2的自然對(duì)數(shù)
Math.LOG2E 以2為底e的對(duì)數(shù)
Math.LOG10E 以10為底e的對(duì)數(shù)
Math.PI π的值
Math.SQRT1_2 1/2 的平方根(即2的平方根的倒數(shù))
Math.SQRT2 2的平方根

2.min() 和 max() 方法
還包含許多方法,用于輔助完成簡(jiǎn)單和復(fù)雜的數(shù)學(xué)計(jì)算倍靡。
其中猴伶,min()和'max()'方法用于確定一組數(shù)值中的最小值和最大值。這兩個(gè)方法都可以接收任意多個(gè)數(shù)值參數(shù)塌西。

var max =Math.max(3, 54, 32, 16);
alert(max);  //54
var min = Math.min(3, 54, 32, 16);
alert(min);  //3

要找到數(shù)組中的最大或最小值他挎,可以像下面這樣使用apply()方法。

var value = [1, 2, 3, 4, 5, 6];
var max = Math.max.apply(Math, values);

這個(gè)技巧的關(guān)鍵是把Math對(duì)象作為apply()的第一個(gè)參數(shù)捡需,從而正確地設(shè)置this值办桨。然后,可以將任何數(shù)組作為第二個(gè)參數(shù)站辉。

3.舍入方法
將小數(shù)值舍入為整數(shù)的幾個(gè)方法:Math.ceil()呢撞、Math.floor()Math.round()饰剥。
這三個(gè)方法分別遵循下列舍入規(guī)則:

  • Math.ceil()執(zhí)行向上舍入
  • Math.floor()執(zhí)行向下舍入
  • Math.round()執(zhí)行標(biāo)準(zhǔn)舍入殊霞,即四舍五入

4.random()方法
Math.random()方法返回介于 0 和 1 之間隨機(jī)一個(gè)隨機(jī)數(shù),不包括 0 和 1汰蓉。
Math.random()從某個(gè)整數(shù)范圍內(nèi)隨機(jī)選擇一個(gè)值绷蹲。

值 = Math.floor(Math.random() * 可能值的總數(shù) + 第一個(gè)可能的值)

如果想要選擇一個(gè)介于 2 到 10 之間的值

var num = Math.floor(Math.random() * 9 +2);

多數(shù)情況下,可以通過(guò)一個(gè)函數(shù)來(lái)計(jì)算可能值的總數(shù)和第一個(gè)可能的值顾孽。

function selectFrom(lowerValue, upperValue) {
  var choices = upperValue - lowerValue + 1;
  return Math.floor(Math.random() * choices + lowerValue);
}
var num = selectFrom(2, 10);
alert(num);  //介于 2 和 10 之間 (包括 2 和 10)的一個(gè)數(shù)值

5.其他方法
下表列出了沒(méi)有介紹到的方法

方法 說(shuō)明
Math.abs(num) 返回絕對(duì)值
Math.exp(num) 返回Math.E的num次冪
Math.log(num) 返回num的自然對(duì)數(shù)
Math.pow(num, power) 返回num的power次冪
Math.sqrt(num) 返回num的平方根
Math.acos(x) 返回x的反余弦值
Math.asin(x) 返回x的反正弦值
Math.atan(x) 返回x的反正切值
Math.atan2(y,x) 返回y/x的反正切值
Math.cos(x) 返回x的余弦值
Math.sin(x) 返回x的正弦值
Math.tan(x) 返回x的正切值

5.8 小結(jié)

對(duì)象在 JavaScript 中被稱為引用類型的值瘸右,而且有一些內(nèi)置的引用類型可以用來(lái)創(chuàng)建特定的對(duì)象娇跟。

  • 引用類型與傳統(tǒng)面向?qū)ο蟪绦蛟O(shè)計(jì)中的類相似,但實(shí)現(xiàn)不同太颤;
  • Object是一個(gè)基礎(chǔ)類型苞俘,其他所有類型都從Object繼承了基本的行為;
  • Array類型是一組值的有序列表龄章,同時(shí)還提供了操作和轉(zhuǎn)換這些值得功能吃谣;
  • Date類型提供了有關(guān)日期和時(shí)間的信息,包括當(dāng)前日期和時(shí)間以及相關(guān)計(jì)算功能做裙;
  • RegExp類型提供了最基本的和一些高級(jí)的正則表達(dá)式功能岗憋。

函數(shù)實(shí)際上是Function類型的實(shí)例,因此函數(shù)也是對(duì)象锚贱;由于函數(shù)是對(duì)象仔戈,所以函數(shù)也擁有方法。
因?yàn)橛辛嘶景b類型拧廊,所以JavaScript中的基本類型可以被當(dāng)作對(duì)象來(lái)訪問(wèn)监徘。三種基本包裝類型分別是:BooleanNumber吧碾、String凰盔。以下是它們共同的特征:

  • 每個(gè)包裝類型都映射到同名的基本類型;
  • 在讀取模式下訪問(wèn)基本類型值時(shí)倦春,就會(huì)創(chuàng)建對(duì)應(yīng)的基本包裝類型的一個(gè)對(duì)象户敬,從而方便了數(shù)據(jù)操作;
  • 操作基本類型值的語(yǔ)句一經(jīng)執(zhí)行完畢睁本,就會(huì)立即銷毀新創(chuàng)建的包裝對(duì)象尿庐。

在所有代碼執(zhí)行之前,作用域中就已經(jīng)存在兩個(gè)內(nèi)置對(duì)象:GlobalMath呢堰。Web 瀏覽器實(shí)現(xiàn)了承擔(dān)該角色的window對(duì)象抄瑟。全局變量和函數(shù)都是Global對(duì)象的屬性。Math對(duì)象提供了很多屬性和方法暮胧,用于輔助完成復(fù)雜的數(shù)學(xué)計(jì)算任務(wù)锐借。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市往衷,隨后出現(xiàn)的幾起案子钞翔,更是在濱河造成了極大的恐慌,老刑警劉巖席舍,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件布轿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)汰扭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門稠肘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人萝毛,你說(shuō)我怎么就攤上這事项阴。” “怎么了笆包?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵环揽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我庵佣,道長(zhǎng)歉胶,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任巴粪,我火速辦了婚禮通今,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肛根。我一直安慰自己辫塌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布晶通。 她就那樣靜靜地躺著璃氢,像睡著了一般哟玷。 火紅的嫁衣襯著肌膚如雪狮辽。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天巢寡,我揣著相機(jī)與錄音喉脖,去河邊找鬼。 笑死抑月,一個(gè)胖子當(dāng)著我的面吹牛树叽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谦絮,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼题诵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了层皱?” 一聲冷哼從身側(cè)響起性锭,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叫胖,沒(méi)想到半個(gè)月后草冈,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年怎棱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哩俭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拳恋,死狀恐怖凡资,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谬运,我是刑警寧澤讳苦,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站吩谦,受9級(jí)特大地震影響鸳谜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜式廷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一咐扭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧滑废,春花似錦蝗肪、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至俺陋,卻和暖如春豁延,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腊状。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工诱咏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缴挖。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓袋狞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親映屋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苟鸯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容