JS權(quán)威指南讀書筆記

第三章 ?類型业簿、值和變量

1、存取字符串阳懂、數(shù)字或布爾值的屬性時創(chuàng)建的臨時對象稱做包裝對象梅尤,它只是偶爾用來區(qū)分字符串值和字符串對象、數(shù)字和數(shù)值對象以及布爾值和布爾對象岩调。

由于字符串不是對象巷燥,但是卻有相應(yīng)的屬性,比如length屬性誊辉。這時JavaScript就會將字符串通過調(diào)用new String()的方式轉(zhuǎn)換成對象矾湃,這個對象繼承了字符串的方法。同時這個對象是一個臨時對象堕澄,一旦屬性引用結(jié)束邀跃,這個新創(chuàng)建的對象就會銷毀。

2蛙紫、對象到字符串的轉(zhuǎn)換步驟:

如果對象具有toString()方法拍屑,則調(diào)用這個方法。如果它返回一個原始值坑傅,JavaScript將這個值轉(zhuǎn)換為字符串僵驰,并返回這個結(jié)果。

如果對象沒有toString()方法唁毒,或者這個方法并不返回一個原始值蒜茴,那么JavaScript會調(diào)用valueOf()方法。如果存在這個方法浆西,則JavaScript調(diào)用它粉私。如果返回值是原始值,JavaScript將這個值轉(zhuǎn)換為字符串近零,并返回結(jié)果诺核。

如果JavaScript無法從以上2個方法獲取一個原始值抄肖,這時將拋出一個類型錯誤異常。

3窖杀、對象到數(shù)字的轉(zhuǎn)換過程:

如果對象具有valueOf()方法漓摩,后者返回一個原始值,則JavaScript將這個原始值轉(zhuǎn)換為數(shù)字并返回這個數(shù)字入客。

否則管毙,如果對象具有toString()方法,后者返回一個原始值桌硫,則將去轉(zhuǎn)換并返回锅风。

否則,拋出類型錯誤異常鞍泉。(TypeError)

toString()的作用是返回一個反映這個對象的字符串皱埠。同時很多類定義了特定版本的該方法。比如咖驮,數(shù)組類的toString()方法將每個數(shù)組元素轉(zhuǎn)換為一個字符串边器,并在元素之間添加逗號后合并成結(jié)果字符串。

valueOf()方法的并未詳細(xì)定義:如果存在任意原始值托修,它就默認(rèn)將對象轉(zhuǎn)換為表示它的原始值忘巧。如果對象是復(fù)合值,就簡單地返回對象本身睦刃。


第四章 表達(dá)式和運(yùn)算符

1砚嘴、原始表達(dá)式是表達(dá)式的最小單位---不再包含其他表達(dá)式。JavaScript原始表達(dá)式包含常量或直接量涩拙、關(guān)鍵字和變量际长。需要注意一點(diǎn)的是,undefined是全局變量兴泥,和null不同工育,不是關(guān)鍵字。當(dāng)JavaScript代碼中出現(xiàn)了標(biāo)識符搓彻,JavaScript會將其當(dāng)做變量去查找它的值如绸。如果變量名不存在,運(yùn)算結(jié)果為undefined旭贬。嚴(yán)格模式中怔接,對不存在的變量進(jìn)行求值會拋出一個引用錯誤。

2稀轨、數(shù)組初始化表達(dá)式是通過一對方括號和數(shù)組內(nèi)逗號隔開的列表構(gòu)成扼脐。數(shù)組直接量中的列表逗號之間的元素可以省略,這時省略的空位會填充undefined靶端。如;

var array = [1,,,,5]; ?//三個元素是undefined.

數(shù)組直接量的元素列表結(jié)尾處可以留下單個逗號谎势,這時并不會創(chuàng)建一個新的值為undefined的元素。

3杨名、屬性訪問表達(dá)式脏榆,在"."和"["之前的表達(dá)式總是會首先計算。如果計算結(jié)果為null或undefined台谍,表達(dá)式就會拋出一個類型錯誤異常须喂,因為這兩個值都不能包含任意屬性。比如:

var obj;
obj.attr? //? Uncaught TypeError: Cannot read property 'attr' of null

4趁蕊、運(yùn)算符

delete --> 刪除屬性
typeof -->檢測操作數(shù)類型
void -->返回undefined值
instanceof -->測試對象類
in -->測試屬性是否存在
坞生,-->忽略第一個操作數(shù),返回第二個操作數(shù)

需要注意的是掷伙,屬性訪問表達(dá)式和調(diào)用表達(dá)式的優(yōu)先級要比所有運(yùn)算符都要高是己。如:

typeof ?my.functions[x](y)
//盡管typeof是優(yōu)先級最高的運(yùn)算符之一,但typeof是在兩次屬性訪問和函數(shù)調(diào)用之后執(zhí)行的任柜。

一元操作符卒废、賦值和三元條件運(yùn)算符都具有從右至做的結(jié)合性。比如:

x = ~-y;
w = x = y = z;
q = a?b:c?d:e?f:g;
//等價于一下代碼
x = ~(-y);
w = (x = (y = z));
q = a?b:(c?d:(e?f:g));

1)子表達(dá)式的運(yùn)算順序

運(yùn)算符的優(yōu)先級是嚴(yán)格按照規(guī)定宙地,但是并沒有規(guī)定子表達(dá)式的計算過程中的運(yùn)算順序摔认。
JavaScript總是嚴(yán)格按照從左至右的順序來計算表達(dá)式。例如:
在表達(dá)式w = x + y * z中宅粥,將首先計算子表達(dá)式w参袱,然后計算x、y和z秽梅。然后抹蚀,y的值和z的值相乘,再加上x的值企垦,最后將其賦值給表達(dá)式w所指代的變量或?qū)傩浴?/p>

5况鸣、算術(shù)表達(dá)式

算術(shù)運(yùn)算符進(jìn)行運(yùn)算時,所有無法轉(zhuǎn)換為數(shù)字的操作符都轉(zhuǎn)換為NaN值竹观。如果操作數(shù)或者轉(zhuǎn)換結(jié)果為NaN值镐捧,算術(shù)運(yùn)算的結(jié)果也為NaN。求余結(jié)果的符號和第一個操作數(shù)的符號保持一致臭增。

NaN + NaN ?
NaN - NaN ?
NaN * NaN ?
NaN / NaN
NaN % NaN
0/0
// ?以上運(yùn)算結(jié)果均為NaN

1) "+"運(yùn)算符

總的來說懂酱,加號的轉(zhuǎn)換規(guī)則優(yōu)先考慮字符串鏈接。如果兩個操作數(shù)不是類字符串的誊抛,那么將進(jìn)行算術(shù)加法運(yùn)算列牺。

加法操作符的完整行為表現(xiàn)為:

如果其中一個操作數(shù)是對象,則對象會遵循對象到原始值得轉(zhuǎn)換規(guī)則轉(zhuǎn)換為原始類值:日期對象通過toString()方法執(zhí)行轉(zhuǎn)換拗窃,其他對象則通過valueOf()方法執(zhí)行轉(zhuǎn)換瞎领。由于對數(shù)對象不具備可用的valueOf()方法泌辫,因此會通過toString()方法來執(zhí)行轉(zhuǎn)換。

進(jìn)行對象到原始值的轉(zhuǎn)換后九默,如果其中一個操作數(shù)是字符串的話震放,另一個操作數(shù)也會轉(zhuǎn)換為字符串,然后進(jìn)行字符串連接驼修。

否則殿遂,兩個操作數(shù)都將轉(zhuǎn)換為數(shù)字(或NaN),然后進(jìn)行加法運(yùn)算乙各。

舉個例子:

1 + 2? // 3:加法
"1" + "2"? //"12":字符串連接
"1" + 2? //"12":數(shù)字轉(zhuǎn)換為字符串后進(jìn)行字符串連接
1 + {}? // "1[object Object]":對象轉(zhuǎn)換為字符串后進(jìn)行字符串連接
true + true ?// 2:布爾值轉(zhuǎn)換為數(shù)字相加
2 + null ?// ?2:null轉(zhuǎn)換為0后做加法
2 + undefined // NaN:undefined轉(zhuǎn)換為NaN后相加

2) 一元算術(shù)運(yùn)算符

一元運(yùn)算符作用于一個單獨(dú)的操作數(shù)墨礁,并產(chǎn)生一個新值。必要時耳峦,他們會將操作數(shù)轉(zhuǎn)換為數(shù)字恩静。所以表達(dá)式++x不總和x = x + 1完全一樣。"++"運(yùn)算符從不進(jìn)行字符串連接操作蹲坷,它總是會將操作數(shù)轉(zhuǎn)換為數(shù)字并增1蜕企。如果x是字符串"1",++x就是先將字符串轉(zhuǎn)換為數(shù)字同時增1冠句,即2轻掩。而x + 1的結(jié)果是字符串"11"。

第五章 語句

嚴(yán)格模式與非嚴(yán)格模式的區(qū)別(前三條很重要):

1懦底、在嚴(yán)格模式下禁止使用with語句唇牧。
2、在嚴(yán)格模式中聚唐,所有變量都要先聲明丐重。如果給一個未聲明的變量、函數(shù)杆查、函數(shù)參數(shù)扮惦、catch從句參數(shù)或全局對象的屬性賦值,將拋出錯誤亲桦。(非嚴(yán)格模式中崖蜜,隱式聲明的全局變量的方法是給全局對象新添加一個新屬性)。
3客峭、在嚴(yán)格模式中豫领,調(diào)用的函數(shù)中的一個this值是undefined。(非嚴(yán)格模式中舔琅,調(diào)用的函數(shù)中的this總是全局對象等恐,比如window)。
4、嚴(yán)格模式中课蔬,當(dāng)通過call()或apply()來調(diào)用函數(shù)時囱稽,其中的this值就是通過call()或apply()傳入的第一個參數(shù)。(非嚴(yán)格模式中二跋,null和undefined值被全局對象和轉(zhuǎn)換為對象的非對象值所代替)战惊。
5、嚴(yán)格模式中同欠,給只讀屬性賦值和給不可擴(kuò)展的對象創(chuàng)建新成員會拋出類型錯誤(非嚴(yán)格模式下,只是操作失敗横缔,并不報錯)铺遂。
6、嚴(yán)格模式中茎刚,函數(shù)里的arguments對象擁有傳入函數(shù)值的靜態(tài)副本(?不是很理解)膛锭。非嚴(yán)格模式下,arguments里的數(shù)組元素和函數(shù)參數(shù)都是指向同一個值得引用奢入。
7筝闹、嚴(yán)格模式下,當(dāng)delete運(yùn)算符后跟隨非法的標(biāo)識符(如變量腥光、函數(shù)等)時关顷,將拋出語法錯誤。非嚴(yán)格模式中武福,這種delete表達(dá)式什么也不做议双,并返回false。
8捉片、嚴(yán)格模式中平痰,在一個對象直接量中定義兩個或多個同名屬性將產(chǎn)生一個語法錯誤。(非嚴(yán)格模式不會報錯)伍纫。同時在es6中觉增,會進(jìn)行覆蓋,后聲明的會覆蓋先前的翻斟。
9逾礁、嚴(yán)格模式中,函數(shù)聲明中存在兩個或多個同名的參數(shù)將產(chǎn)生一個語法錯誤(非嚴(yán)格模式不報錯)。
10嘹履、嚴(yán)格模式不允許使用八進(jìn)制整數(shù)直接量腻扇。

第六章 對象

創(chuàng)建對象有三種方式,包括對象字面量砾嫉、new和Object.create().

Object.create()接受兩個參數(shù)幼苛。第一個參數(shù)是這個對象的原型。第二個可選參數(shù)用以對對象的屬性進(jìn)行進(jìn)一步描述焕刮。
可以通過傳入?yún)?shù)null來創(chuàng)建一個沒有原型的新對象舶沿,但是通過這種方法創(chuàng)建的對象不會繼承任何東西,甚至不包括基礎(chǔ)方法配并。比如toString()括荡。
如果想創(chuàng)建一個普通的空對象(比如{}),需要傳入Object.prototype:

var obj = Object.create(Object.prototype); // 和new Object()一樣

屬性的查詢和設(shè)置

可以通過點(diǎn)(.)或方括號([])運(yùn)算符來獲取對象屬性的值溉旋。對于點(diǎn)(.)來說畸冲,右側(cè)必須是一個以屬性名稱命名的簡單標(biāo)識符。對于方括號來說([])观腊,方括號內(nèi)必須是一個計算結(jié)果為字符串的表達(dá)式邑闲。更嚴(yán)格地講,表達(dá)式必須返回字符串或返回一個可以轉(zhuǎn)換為字符串的值梧油。需要注意的是苫耸,如果屬性的名字是數(shù)字的話,使用點(diǎn)運(yùn)算符會報錯儡陨,必須使用方括號進(jìn)行查詢鲸阔。

方括號運(yùn)算符的優(yōu)點(diǎn)在于方括號使用字符串值(字符串值是動態(tài)的,可以在運(yùn)行時更改)迄委。而標(biāo)識符是靜態(tài)的褐筛,必須寫死在程序中。

屬性訪問錯誤

查詢一個不存在的屬性并不會報錯叙身,訪問不存在的表達(dá)式會返回undefined渔扎。但是,如果對象不存在信轿,那么試圖查詢不存在的對象的屬性就會報錯晃痴。程序中可以用短路運(yùn)算&&防止此類事情發(fā)生。obj && obj.attr
當(dāng)然财忽,給null和undefined設(shè)置屬性也會報類型錯誤倘核。在一下場景下給對象o設(shè)置屬性p會失敗:

o中的屬性p是只讀的:不能給只讀屬性重新賦值。
o中的屬性p是繼承屬性即彪,并且是只讀的:不能通過同名自有屬性覆蓋只讀的繼承屬性紧唱。
o中不存在自有屬性p:o沒有使用setter方法繼承屬性p,并且o的可擴(kuò)展行是false。如果o中不存在p漏益,而且沒有setter方法可供調(diào)用蛹锰,則p一定會添加至o中。但如果o不是可擴(kuò)展的绰疤,那么在o中不能定義新屬性铜犬。(好拗口)

刪除屬性

delete運(yùn)算符可以刪除對象的屬性。操作數(shù)應(yīng)該是一個屬性訪問表達(dá)式轻庆。delete運(yùn)算符只能刪除自有屬性癣猾,不能刪除繼承屬性。當(dāng)delete表達(dá)式刪除成功或沒有任何副作用(比如刪除不存在的屬性)時余爆,會返回true纷宇。

var o = {};
delete o.x; //刪除不存在的屬性 ?返回true
delete o.toString; //刪除繼承的屬性,但無法刪除 依舊返回true
delete 1; // 運(yùn)算符后不是屬性訪問表達(dá)式龙屉,沒有實際意義呐粘,依舊返回true

delete不能刪除那些可配置性為false的屬性满俗。某些內(nèi)置對象的屬性是不可配置的转捕,比如通過變量聲明和函數(shù)聲明創(chuàng)建的全局對象的屬性。

檢測屬性

首先是in運(yùn)算符唆垃。in運(yùn)算符的左側(cè)是屬性名(需是字符串)五芝,右側(cè)是對象。如果對象的自有屬性或繼承屬性中包含則返回true辕万。(敲重點(diǎn)枢步,對象的自有屬性或繼承屬性)

還有hasOwnProperty()方法。該方法用來檢測給定的名字是否是對象的自有屬性渐尿。繼承屬性會返回false醉途。(敲重點(diǎn),自有屬性返回true砖茸,其他的包括繼承的返回false)

propertyIsEnumerable()是hasOwnProperty()的增強(qiáng)版隘擎,只有檢測到是自有屬性并且這個屬性的可枚舉性為true時才返回true。一般來說凉夯,JS代碼創(chuàng)建的都是可枚舉的货葬。

可以使用!==來判斷某個屬性是否為undefined。但是in可以區(qū)分不存在的屬性和存在值為undefined的屬性劲够。也就是說震桶,某個屬性顯示賦值為undefined時,in返回true征绎,而不全等則返回false蹲姐。

var o = {x:1};
"x" in o; // true
"toString" in o // 繼承屬性,返回true
o.hasOwnProperty("x"); // 自身屬性,返回true
o.hasOwnProperty("toString"); // 繼承屬性淤堵,返回false
o.propertyIsEnumerable("x"); //可枚舉的自身屬性寝衫,返回true

枚舉屬性

for/in循環(huán)可以遍歷對象中所有可枚舉的屬性,包括繼承的拐邪。還有兩個ES5定義的枚舉屬性名稱的函數(shù)慰毅。第一個是Object.keys(),它返回一個數(shù)組扎阶,數(shù)組由對象可枚舉的自有屬性的名稱組成汹胃。第二是Object.getOwnPropertyNames(),返回對象的所有自有屬性的名稱,包括不可枚舉的东臀!也就是說兩者都是返回自身屬性着饥,只不過前者無法返回不可枚舉的,后者可以返回不可枚舉的惰赋。

var o = {x:1,y:2};
Object.keys(a); //["x","y"],返回自身可枚舉屬性名稱的數(shù)組
Object.getOwnPropertyNames(a); //["x", "y"]
//本例沒有不可枚舉屬性宰掉,所以兩者返回相同的數(shù)組

對象的三個屬性

1)原型屬性

對象的原型屬性是用來繼承屬性的。原型屬性是在實例對象創(chuàng)建之初就設(shè)置好的赁濒。通過對象直接量的對象使用Object.prototype作為原型轨奄。通過new創(chuàng)建的對象使用構(gòu)造函數(shù)的prototype屬性作為原型。通過Object.create()創(chuàng)建的對象使用第一個參數(shù)作為原型拒炎。

如若檢測一個對象是否是另一個對象的原型(或處于原型鏈中)挪拟,請使用isPrototypeOf()方法

var p = {x:1};
var o = Object.create(p); //使用p原型創(chuàng)建對象
p.isPrototypeOf(o); //true
Object.prototype.isPrototypeOf(o); //true 均為繼承

第七章 數(shù)組

如果省略數(shù)組直接量中的某個值击你,省略的元素的值為undefined玉组。

var count = [1,,3]; // count[1]的值為undefined
var undefs = [,,]; //undefs.length為2,數(shù)組直接量的語法允許有可選的結(jié)尾逗號,所以[,,]只有2個元素丁侄,而不是3個惯雳。

數(shù)組的元素的讀和寫

使用[]操作符來訪問數(shù)組。方括號中是一個返回非負(fù)整數(shù)值得任意表達(dá)式鸿摇。數(shù)組是對象的特殊形式石景,使用[]訪問數(shù)組元素就像用方括號訪問對象屬性一樣。數(shù)組的特別之處在于户辱,當(dāng)使用小于2^32的非負(fù)整數(shù)作為屬性名時數(shù)組會自動維護(hù)其length屬性值鸵钝。舉個例子:

var a = [];
a[1] = 1;
a[2] = 2;
a.length? //? => 3
//也就是說,給數(shù)組a賦值小于2^32的非負(fù)整數(shù)的屬性名時庐镐,數(shù)組會自動擴(kuò)展為其length屬性值恩商。但是,屬性值超過2^32的正整數(shù)或者負(fù)數(shù)時必逆,就不會維護(hù)為length屬性值了怠堪。接著看下面的例子
var b = [];
b[Math.pow(2,32)] = 3;
b;? //? ? => [4294967296: 3];
b[-1] = 4;
b;? //? ? => [4294967296: 3, -1: 4]

所有的索引都是屬性名揽乱,但只有在0~2^32 - 2之間的整數(shù)屬性名才是索引。
可以使用負(fù)數(shù)或者非整數(shù)來索引數(shù)組粟矿。這種情況下凰棉,數(shù)值會轉(zhuǎn)換為字符串,字符串作為屬性名來用陌粹。因為此情況為非負(fù)整數(shù)撒犀,所以只能當(dāng)常規(guī)的對象屬性,而非數(shù)組的索引掏秩。舉個例子:

a[-1.23] = true; ?// 創(chuàng)建名為‘-1.23’的屬性
a["1000"] = 0; ?//數(shù)組的第1001個元素
a[1.000] ?//等同于a[1]

數(shù)組索引僅僅是對象屬性名的一種特殊類型或舞,意味著數(shù)組沒有越界錯誤的概念。也就是說蒙幻,當(dāng)試圖查詢?nèi)魏螌ο笾胁淮嬖诘膶傩詴r映凳,不會報錯,僅僅得到undefined值邮破。

稀疏數(shù)組

稀疏數(shù)組就是包含從0開始的不連續(xù)索引的數(shù)組诈豌。意味著稀疏數(shù)組length屬性值大于元素的個數(shù)。最簡單粗暴的創(chuàng)建稀疏數(shù)組的方式:var a = new Array(10); 0個元素抒和,長度為10矫渔。

足夠稀疏的數(shù)組通常在實現(xiàn)上比稠密的數(shù)組更慢、內(nèi)存利用率更高构诚,在這樣的數(shù)組中查找元素的事件與常規(guī)對象屬性的查找時間一樣長蚌斩。在數(shù)組直接量中省略值時不會創(chuàng)建稀疏數(shù)組铆惑。因為省略的元素在數(shù)組中是存在的范嘱,值為undefined。這和元素不存在還是有區(qū)別的员魏,請看下例:

var a1 = [,,,];? //? =>[undefined,undefined,undefined]
var a2 = new Array(3); ? // ?=>數(shù)組根本沒有元素
0 in a1 ? ?// ? =>true;因為a1在索引0處有元素丑蛤,為undefined
0 in a2 ? // ? ?=>false; ?a2在索引0處沒有元素

數(shù)組長度

如果為一個數(shù)組元素賦值,它的索引i大于或等于現(xiàn)有數(shù)組的長度時撕阎,length屬性的值將設(shè)置為 ? i + 1受裹。相對的,設(shè)置length屬性為一個小于當(dāng)前長度的非負(fù)整數(shù)n時虏束,當(dāng)前數(shù)組中那些索引值大于等于n的元素將被刪除:

var a = [1,2,3,4,5];?
a.length = 0; ? //刪除所有元素棉饶,a為[]
a.length = 5; ? //等同于new Array(5)

刪除數(shù)組元素與為其賦undefined值得類似的。對一個數(shù)組元素使用delete不會修改數(shù)組的length屬性镇匀,也不會將元素從高索引出移下來填充已刪除屬性的空白照藻。如果刪除元素,就會變成稀疏數(shù)組汗侵。

數(shù)組方法

1)join()----------不會改變原數(shù)組

Array.join()將數(shù)組中所有元素都轉(zhuǎn)化為字符串并連接在一起幸缕,返回最后生成的字符串群发。可以指定可選的字符串在生成的字符串中分隔數(shù)組元素发乔。默認(rèn)使用逗號熟妓。Array.join()是String.split()方法的逆向操作,后者根據(jù)指定正則來分割字符串為一個數(shù)組栏尚。

var a = [1,2,3];
a.join();? //? ? =>"1,2,3"
a.join(" ");? //? ? =>"1 2 3"
var b = new Array(10);
b.join('-')? ? //? ? => "---------"

2)reverse()---------會改變原數(shù)組

Array.reverse()方法將數(shù)組中的元素顛倒順序起愈,返回逆序的數(shù)組。需要注意的是译仗,該方法是在原先的數(shù)組中重新排列告材。

var a = [1,2,3];
a.reverse(); ? // ? => [3,2,1]
a;// ? => [3,2,1]

3)? sort() ---------會改變原數(shù)組

該方法將數(shù)組中的元素排序并返回排序后的數(shù)組。當(dāng)不帶參數(shù)調(diào)用時古劲,數(shù)組元素以字母表順序排序(有必要時臨時轉(zhuǎn)化為字符串進(jìn)行比較)斥赋。如果數(shù)組包含undefined元素,會被排到數(shù)組的尾部产艾。

該方法可以傳一個可選的參數(shù)疤剑,參數(shù)必須是函數(shù)。也就是所謂的比較函數(shù)比較函數(shù)應(yīng)該具備兩個參數(shù)a和b闷堡,返回值如下:
若a小于b隘膘,在排序后的數(shù)組中a應(yīng)該出現(xiàn)在b之前,則返回一個小于0的值杠览。
若a等于b弯菊,則返回0。
若a大于b踱阿,則返回一個大于0的值管钳。

下面是一個打算數(shù)字?jǐn)?shù)組的順序的方法:

var sortArray = array.sort(function(){
? ? return Math.random() - 0.5;
})

4) ?concat() ?---------不會改變原數(shù)組

該方法創(chuàng)建并返回一個新數(shù)組,元素包括調(diào)用concat()的原始數(shù)組的元素和該方法的每個參數(shù)软舌。concat()不會修改調(diào)用的方法才漆。而且concat()不會遞歸扁平化數(shù)組的數(shù)組。如果不傳參數(shù)佛点,則返回調(diào)用該方法的數(shù)組醇滥,也就相當(dāng)于對數(shù)組進(jìn)行了一次復(fù)制(淺復(fù)制)。

var a = [1,2,3];
a.concat(4,5);
a.concat([4,5]); ?// ?=>均返回[1,2,3,4,5]

5) slice() ---------不會改變原數(shù)組,該單詞含義為切片超营,劃分
該方法返回指定數(shù)組的一個片段或者子數(shù)組鸳玩。兩個參數(shù)分別指定了片段的開始和結(jié)束的位置⊙荼眨可以簡單的理解為左閉右開([start,end))不跟。如果只指定一個參數(shù),返回的數(shù)組包含從開始位置到結(jié)尾的所有元素船响。如果單參數(shù)為負(fù)數(shù)躬拢,則開始位置從最后一個元素開始躲履。

var a = [1,2,3,4,5];
a.slice(0,3); ? // ?=>索引從[0,3),不包含第4個元素聊闯,返回[1,2,3]
a.slice(3); ? // ?=>從a[3]開始到最后一個元素工猜,返回[4,5]

6) splice() -------------會改變原數(shù)組,該單詞含義為粘接

該方法能夠從數(shù)組中刪除元素、插入元素到數(shù)組中或者同時完成刪除和插入菱蔬。使用該方法后篷帅,數(shù)組元素會根據(jù)需要增加或減小索引值,因此數(shù)組的其他部分仍然是連續(xù)的拴泌。第一個參數(shù)指定了插入魏身、刪除的起始位置。第二個參數(shù)指定應(yīng)該從數(shù)組中刪除元素的個數(shù)蚪腐。若省略第二元素箭昵,從起始點(diǎn)到結(jié)尾所有元素都會被刪除。splice()返回一個有刪除元素組成的數(shù)組回季,或者如果沒刪除元素就返回空數(shù)組家制。splice()的前兩個參數(shù)指定了需要刪除的數(shù)組元素。后面的任意參數(shù)指定了需要插入到數(shù)組中的元素泡一,從第一個參數(shù)指定的位置開始插入颤殴。也就是說,第一個參數(shù)是刪除或插入的起始位置鼻忠。舉個例子:

var a = [1,2,3,4,5,6,7,8];
a.splice(4); ? ?// 指定一個參數(shù)涵但,意味著從a[4]開始到末尾都會被刪除,此時會返回 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//[5,6,7,8],然后原數(shù)組a變?yōu)閇1,2,3,4]?
a.splice(1,2); ? //注意此時原數(shù)組為[1,2,3,4],兩個參數(shù)指定了從a[1]開始刪除2個元素帖蔓,返 ? ? ? ? ? ? ? ? ? ? ? ? ?//回[2,3]翻屈,同時原數(shù)組變?yōu)閇1,4]
a.splice(1,0,[1,2],3); ? //此時方法多于2個參數(shù)晌端,意味著會進(jìn)行刪除和插入操作俐末。從a[1]開始刪除0個元素聚蝶,同時在指定位置左側(cè)插入'[1,2],3',由于刪除了0個元素篡殷,所以會返回[]钝吮,同時a變?yōu)閇1,[1,2],3,4]

項目中遇到了對列表上移和下移的需求,剛好用到了splice板辽,大致代碼如下:

//? 對selectItem數(shù)組上移操作
if(!index)return;//如果是第一項就返回奇瘦,第一項當(dāng)然不允許上移了
this.selectItem.splice(index-1,0,(this.selectItem[index]));
//既然要上移,那我們肯定要插入到前一項的左側(cè)了劲弦,所以第一個參數(shù)是index-1,然后第三參數(shù)將當(dāng)前項插入到數(shù)組中耳标,注意此時是有2個當(dāng)前項的,假設(shè)我們是對數(shù)組的第二項進(jìn)行操作的邑跪,那么現(xiàn)在返回的數(shù)組第一項和第三項都是進(jìn)行上移的那一項次坡,所以我們必須刪除重復(fù)的呼猪。
this.selectItem.splice(index+1,1);
//我們來進(jìn)行刪除操作,注意現(xiàn)在新數(shù)組的第一項和第三項都是我們移動的那個值砸琅,而當(dāng)前index為1宋距,所以我們需要操作index+2,也就是第三項症脂,將其刪除谚赎。

//下移
if(index ===this.selectItem.length -1)return;//如果為最后一項 ,不允許下移
this.selectItem.splice(index+2,0,(this.selectItem[index]));
//既然要下移诱篷,那么我們就要將當(dāng)前數(shù)據(jù)插入到下下位的左側(cè)了壶唤,如果是index+1,那還是在原來的地方多了一個重復(fù)的數(shù)據(jù),等于沒移動棕所!
this.selectItem.splice(index,1);
// 這個好理解闸盔,直接將原來的值刪除即可。

7) push()和pop() ------------會修改原數(shù)組
push()在數(shù)組尾部添加一個或多個元素琳省,返回數(shù)組新的長度蕾殴。pop()刪除數(shù)組的最后一個元素,同時返回刪除的那個值岛啸。來總結(jié)一下钓觉,兩個方法都是在數(shù)組尾部操作,而且push支持多個參數(shù)坚踩,pop不傳參數(shù)荡灾,就算傳了參數(shù)也會忽略參數(shù),而且只能刪除最后一個元素并返回這個值瞬铸。

8) unshift()和shift() ----------會修改原數(shù)組
這兩個方法跟上面的方法十分類似批幌,只不過是修改的數(shù)組的頭部而非尾部。unshift()對應(yīng)push()方法嗓节,在數(shù)組頭部添加一個或多個元素荧缘,并將已存在的元素移動到更高索引的位置來獲得足夠的空間,最后返回數(shù)組新的長度拦宣。shift()對應(yīng)pop()方法截粗,刪除第一個元素并返回,將隨后的元素下移一個位置填補(bǔ)空缺鸵隧。
值得注意的一個地方绸罗,unshift()使用多個參數(shù)調(diào)用時,參數(shù)是一次性插入的豆瘫,而不是一個個的插入珊蟀。這意味著最終的數(shù)組中插入元素的順序和在參數(shù)中的順序保持一致,如果每次插入一個參數(shù)外驱,則恰好反過來育灸。來個例子:

var a= [3];
a.unshift(1,2); ? // ?返回數(shù)組長度3腻窒,此時a為[1,2,3];
a.unshift(1); // 2
a.unshift(2); ?// 3 ?此時a為[2,1,3]

這兩對好基友可以讓數(shù)組實現(xiàn)類似隊列的效果(FIFO):
push()在數(shù)組尾部將元素添加,shift()在數(shù)組頭部將元素刪除磅崭;<-------
unshift()在數(shù)組頭部將元素添加定页,pop()在數(shù)組尾部將元素刪除;------->

9) toString()和toLocaleString()

數(shù)組同樣也擁有toString()方法绽诚。該方法將每個元素轉(zhuǎn)化為字符串典徊,有必要的話還會調(diào)用元素的toString()方法。并且輸出用逗號分隔的字符串列表恩够。要注意的是卒落,輸出不包括方括號或者其他任何形式的包裹數(shù)組值得分隔符。結(jié)果與不使用任何參數(shù)調(diào)用join()方法返回的字符串相同蜂桶。

[1,2,3].toString() ? ? ? ? ? ?// ?'1,2,3'
["a","b","c"].toString() ? ?// ?'a,b,c'

toLocaleString()是toString()方法本地化版本儡毕。

ES5中的數(shù)組方法

大多數(shù)方法的第一個參數(shù)接收一個函數(shù),并且對數(shù)組的每個元素或一些元素調(diào)用該函數(shù)扑媚。也就是說腰湾,大多是方法是對數(shù)組進(jìn)行遍歷的。如果是稀疏數(shù)組疆股,對不存在的元素不調(diào)用傳遞的參數(shù)费坊。大部分情況下,調(diào)用的函數(shù)提供三個參數(shù):數(shù)組元素旬痹、元素的索引和數(shù)組本身(item,index,array)附井。第二個參數(shù)是可選的,如果有的話两残,則調(diào)用的函數(shù)被看做是第二個參數(shù)的方法永毅。也就是說,在調(diào)用函數(shù)時傳遞進(jìn)去的第二個參數(shù)作為它的this關(guān)鍵字的值來使用人弓。
ES5的數(shù)組方法都不會修改原數(shù)組沼死。

1)forEach()
這個已經(jīng)用的很多了,說一個注意點(diǎn)崔赌。forEach()無法提前終止遍歷意蛀。如果要提前終止,必須把方法放在一個try塊中峰鄙,并能拋出一個異常浸间。

2) ?map()
該方法將調(diào)用的數(shù)組的每個元素傳遞給指定函數(shù),并返回一個新的數(shù)組吟榴,包含函數(shù)的返回值。
所以map()的函數(shù)參數(shù)應(yīng)該有返回值囊扳。如果是稀疏數(shù)組吩翻,返回的也是相同方式的稀疏數(shù)組:相同的長度兜看,相同的缺失元素。
經(jīng)實踐狭瞎,如果在函數(shù)中進(jìn)行break细移,會報錯。如果對滿足某個條件的元素return,則該元素對應(yīng)的位置為undefined,如果return其他值熊锭,則該位置為對應(yīng)值弧轧,包括return false。

var a = [1,2,3];
a.map(function(x){
? ? ? ? if (x === 2)? return;
? ? ? ? return x + x;
});? ? //? [2, undefined, 6]
a.map(function(x){
? ? ? ? if (x === 2) return false;
? ? ? ? return x + x;
});? //? [2, false, 6]

3) ?filter()
該方法返回的數(shù)組元素是調(diào)用的數(shù)組的一個子集碗殷。如果返回值為true或能轉(zhuǎn)化為true的值精绎,那么傳遞給判定函數(shù)的元素就是這個子集的成員。方法會跳過稀疏數(shù)組中缺少的元素锌妻,它的返回數(shù)組總是稠密的代乃。

4)every()和some()
兩個方法是數(shù)組的邏輯判定:它們對數(shù)組元素應(yīng)用指定的函數(shù)進(jìn)行判定,返回true或false仿粹。
如果數(shù)組中的所有元素調(diào)用判定函數(shù)全部都返回true搁吓,every()方法才返回true,其他一律返回false吭历。如果數(shù)組中至少有一個元素調(diào)用判定函數(shù)返回true堕仔,它就返回true。只有所有的元素調(diào)用判定函數(shù)返回false晌区,它才返回false贮预。

var a = [1,2,3,4,5];
a.every(function(x) {return x % 2 === 0;})? // false? 不是所有數(shù)都是偶數(shù)
a.some(function(x) {return x % 2 === 0;}) ? //true ? 含有偶數(shù)

5) reduce()和reduceRight()
方法使用指定的函數(shù)將數(shù)組元素進(jìn)行組合,生成單個值契讲。
reduce()需要兩個參數(shù)仿吞,第一個是執(zhí)行化簡操作的函數(shù)〖衿化簡函數(shù)的任務(wù)就是用某種方法把兩個值合成為一個值唤冈,并返回。第一次調(diào)用函數(shù)時银伟,第一個參數(shù)是一個初始值你虹,就是傳遞給reduce()的第二個參數(shù)。下一次調(diào)用中彤避,這個值就是上次化簡函數(shù)的返回值傅物。舉個例子:

var a = [1,2,3,4,5];
var sum = a.reduce(function(x,y){return x+y},0);

在這個例子中,第一次調(diào)用化簡函數(shù)時的參數(shù)是0(化簡函數(shù)的第二個參數(shù)琉预,即初始值)和1(數(shù)組的第一項),將兩個相加返回1董饰,再次調(diào)用的時候參數(shù)為返回值1和數(shù)組的第二項2,然后返回3。依次相加得到15卒暂,reduce方法返回這個值啄栓。

當(dāng)不指定初始值調(diào)用reduce()時,它將使用數(shù)組的第一個元素作為初始值也祠。這意味著第一次調(diào)用化簡函數(shù)的時候就使用第一個和第二個數(shù)組元素作為第一和第二個參數(shù)昙楚。但是在空數(shù)組上,不帶初始值參數(shù)調(diào)用reduce()將導(dǎo)致類型錯誤異常诈嘿。如果調(diào)用它的時候只有一個值(數(shù)組只有一個元素并且沒有指定初始值堪旧,或者有一個空數(shù)組并且指定了一個初始值),reduce()只是簡單地返回那個值而不會調(diào)用化簡函數(shù)奖亚。

reduceRight()與reduce()不同的是淳梦,它按照數(shù)組索引從高到低來處理數(shù)組。

5) indexOf()與lastIndexOf()
方法搜索整個數(shù)組中具有給定值得元素遂蛀,返回找到的第一個元素的索引或沒有找到就返回-1谭跨。
indexOf()從頭至尾搜索,lastIndexOf()相反李滴。
兩個方法不接受一個函數(shù)作為參數(shù)螃宙。他們的參數(shù)是這樣的:第一個參數(shù)是需要搜索的值,第二個參數(shù)是可選的所坯,指定數(shù)組中的一個索引谆扎,從索引出開始搜索。第二個參數(shù)也可以是負(fù)數(shù)芹助,代表相對數(shù)組末尾的偏移量堂湖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市状土,隨后出現(xiàn)的幾起案子无蜂,更是在濱河造成了極大的恐慌,老刑警劉巖蒙谓,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斥季,死亡現(xiàn)場離奇詭異,居然都是意外死亡累驮,警方通過查閱死者的電腦和手機(jī)酣倾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谤专,“玉大人躁锡,你說我怎么就攤上這事≈檬蹋” “怎么了映之?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵拦焚,是天一觀的道長。 經(jīng)常有香客問我惕医,道長耕漱,這世上最難降的妖魔是什么算色? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任抬伺,我火速辦了婚禮,結(jié)果婚禮上灾梦,老公的妹妹穿的比我還像新娘峡钓。我一直安慰自己,他們只是感情好若河,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布能岩。 她就那樣靜靜地躺著,像睡著了一般萧福。 火紅的嫁衣襯著肌膚如雪拉鹃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天鲫忍,我揣著相機(jī)與錄音膏燕,去河邊找鬼。 笑死悟民,一個胖子當(dāng)著我的面吹牛坝辫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播射亏,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼近忙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了智润?” 一聲冷哼從身側(cè)響起及舍,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窟绷,沒想到半個月后锯玛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钾麸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年更振,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饭尝。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡肯腕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钥平,到底是詐尸還是另有隱情实撒,我是刑警寧澤姊途,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站知态,受9級特大地震影響捷兰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜负敏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一贡茅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧其做,春花似錦顶考、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蹈胡,卻和暖如春渊季,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罚渐。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工却汉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搅轿。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓病涨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親璧坟。 傳聞我的和親對象是個殘疾皇子既穆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

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