JavaScript高級程序設計學習(四)之引用類型
在javascript中也是有引用類型的,java同樣如此。
javascript常見也比較常用的引用類型就熟Object和Array。
一個對象和一個數組,這個在前後端分離開發中也用的最多。比如ajax傳參,有時我不僅僅只是需要一個參數,例如添加方法,傳的是一個對象,對象存在屬性。在java中對象也可以說類。因為類存在屬性,例如人類,他的屬性有身高,體重,姓名,年齡,性別等。而js對象,也可以這樣,比如車,它可以有品牌,顏色,造型等等。
js對象可以做什麽呢?同java對象有什麽區別呢?
第一,如果要問題js對象可以做什麽,最簡單最直白最實用,我可以將一些公共屬性放到這個對象中,然而我只需對象.屬性,即可擁有。別說這個不常用,比如項目路徑,全局變量等,都可以這樣做。這樣的話,代碼會得到一定的規範。代碼規範是很重要的,這個對於初學者而言,要牢記。不規範導致的只是無止休的重復勞動。
第二,js對象方便異步ajax傳參,無論是react或者vue.js,我相信異步傳參基本還是要用對象的;
作為IT從業者而言,時間對於我們就是金錢。時間是非常寶貴的,因為時間讓我們增長自己的知識才能,在這個培訓機構眾多,競爭者眾多的IT界中,如果一昧著抱著做好本職工作其他不管不問是非常危險的。因為那樣會使人變得安逸。如果要問程序員最怕什麽?或許有人說,最怕找不到對象。還有人說,最怕長白頭發,更有人說最怕猝死在電腦旁。如果要問我說,那個有道理,我只能回答都有道理。
但在我看來程序員最怕的就是沒有鬥誌,沒有上進心,因為缺乏了這兩樣,可以說從今以後就停滯不前了。
最近聽到不少人說,幹著重復的事,寫著重復的代碼,真沒意思。的確,業務代碼確實就那一套,沒多大變化,但是呢?也別小瞧業務代碼。業務代碼,的確有重復的。說到重復性,我想起了封裝想起了繼承。記得我哥對我說過,當頁面或好幾個類引用同樣的代碼時,你能不能想個什麽辦法呢?將其封裝反復利用。這樣一行代碼的事可以解決好幾個類引用的問題。
數組可以做什麽呢?
js的數組應用場景的話,結合mybatis,可以實現批量修改,批量分發功能。
有的時候,例如,復選框,復選框的話,特別在博客方面,比如一篇文章,它跟類型或許是一對一或多對一的關系,但是標簽的話,多對多關系,多篇文章對應多個標簽。博客園上面本身就有示例。
檢測對象或Array類型可使用instanceof修飾符
(1)棧方法
ECMAScript 數組也提供了一種讓數組的行為類似於其他數據結構的方法。具體說來,數組可以表 現得就像棧一樣,後者是一種可以限制插入和刪除項的數據結構。棧是一種 LIFO(Last-In-First-Out, 後進先出)的數據結構,也就是新添加的項早被移除。而棧中項的插入(叫做推入)和移除(叫做 彈出),只發生在一個位置——棧的頂部。ECMAScript為數組專門提供了 push()和 pop()方法,以便 實現類似棧的行為。
<html> <meta charset="utf-8"> <head> <script> 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 </script> </head> <body> </body> </html>
(2)隊列方法
棧數據結構的訪問規則是 LIFO(後進先出),而隊列數據結構的訪問規則是 FIFO(First-In-First-Out, 先進先出)。隊列在列表的末端添加項,從列表的前端移除項。由於 push()是向數組末端添加項的方法, 因此要模擬隊列只需一個從數組前端取得項的方法。實現這一操作的數組方法就是 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
(3)重排序
數組中已經存在兩個可以直接用來重排序的方法:reverse()和 sort()。有讀者可能猜到了, reverse()方法會反轉數組項的順序
var values = [1, 2, 3, 4, 5];
values.reverse();
alert(values); //5,4,3,2,1
sort()方法可以正序,不過通常還是需要加函數判斷的
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); //0,1,5,10,15
(4)操作方法
ECMAScript為操作已經包含在數組中的項提供了很多方法。其中,concat()方法可以基於當前數 組中的所有項創建一個新數組。具體來說,這個方法會先創建當前數組一個副本,然後將接收到的參數 添加到這個副本的末尾,後返回新構建的數組。在沒有給 concat()方法傳遞參數的情況下,它只是 復制當前數組並返回副本。如果傳遞給 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(),它能夠基於當前數組中的一或多個項創建一個新數組。slice()方法可以 接受一或兩個參數,即要返回項的起始和結束位置。在只有一個參數的情況下,slice()方法返回從該 參數指定位置開始到當前數組末尾的所有項。如果有兩個參數,該方法返回起始和結束位置之間的項— —但不包括結束位置的項。註意,slice()方法不會影響原始數組
示例參考:
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
splice()方法,這個方法恐怕要算是強大的數組方法了,它有很多種用法。 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()方法始終都會返回一個數組,該數組中包含從原始數組中刪除的項(如果沒有刪除任何 項,則返回一個空數組)。
示例如下:
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,返回的數組中只包含一項
(5)位置方法
ECMAScript 5為數組實例添加了兩個位置方法: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
var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
alert(people.indexOf(person)); //-1
alert(morePeople.indexOf(person)); //0
(6)叠代方法
ECMAScript 5為數組定義了 5個叠代方法。每個方法都接收兩個參數:要在每一項上運行的函數和 (可選的)運行該函數的作用域對象——影響 this 的值。傳入這些方法中的函數會接收三個參數:數 組項的值、該項在數組中的位置和數組對象本身。根據使用的方法不同,這個函數執行後的返回值可能 會也可能不會影響方法的返回值。以下是這 5個叠代方法的作用。
? every():對數組中的每一項運行給定函數,如果該函數對每一項都返回 true,則返回 true。
? filter():對數組中的每一項運行給定函數,返回該函數會返回 true 的項組成的數組。
? forEach():對數組中的每一項運行給定函數。這個方法沒有返回值。
? map():對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組。
? some():對數組中的每一項運行給定函數,如果該函數對任一項返回 true,則返回 true。 以上方法都不會修改數組中的包含的值
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]
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
//執行某些操作 });
(7)歸並方法
ECMAScript 5 還新增了兩個歸並數組的方法:reduce()和 reduceRight()。這兩個方法都會叠 代數組的所有項,然後構建一個終返回的值。其中,reduce()方法從數組的第一項開始,逐個遍歷 到後。而 reduceRight()則從數組的後一項開始,向前遍歷到第一項。 這兩個方法都接收兩個參數:一個在每一項上調用的函數和(可選的)作為歸並基礎的初始值。傳給 reduce()和 reduceRight()的函數接收 4 個參數:前一個值、當前值、項的索引和數組對象。這 個函數返回的任何值都會作為第一個參數自動傳給下一項。第一次叠代發生在數組的第二項上,因此第 一個參數是數組的第一項,第二個參數就是數組的第二項。
使用 reduce()方法可以執行求數組中所有值之和的操作,比如:
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15
第一次執行回調函數,prev 是 1,cur 是 2。第二次,prev 是 3(1加 2的結果),cur 是 3(數組 的第三項)。這個過程會持續到把數組中的每一項都訪問一遍,後返回結果。 reduceRight()的作用類似,只不過方向相反而已。
var values = [1,2,3,4,5]; var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15
小結上述例子和概念均來自於《JavaScript高級程序設計第三版》這本書,我覺得他的概念和例子很典型,值得借鑒和參考,所以引用。我想既然是系統學習的看這本書,不單單引用,而且還要自己的體會,不然跟抄襲又有什麽區別呢?我相信該作者的本意是想讓程序員們更好的利用js達到web開發最好的效果。
坦白的說上述說的那幾個方法,我一個都沒有在實際開發中用過,但是我覺得它很有用,為什麽呢?實際開發中,為了效率往往我們找自己最熟悉的最常用的,當這些能解決問題時,我們不會考慮其他。所以自然上述用的少或不用。還有一個原因常用的,我們知道它通常的出錯可能性,或者運行後,會有什麽效果,我們都一清二楚,因為常用的緣故,而不常用和沒用過,有的時候需要用瀏覽器不斷的調試很久才找到原因。這就好像,為什麽很多人寧願用mybatis自己手寫sql和代碼,也不願意用mybatis plus或jeesite,原因很大程度因為風險不可控。對於項目而言,風險可控是個很重要的事情。
另外上述的代碼雖然是借鑒該書,但是我強烈建議朋友們,學習時或者看該篇文章時,還是要抱著“知行合一”的概念。每閱讀一小塊,加以實踐。這樣也不失為一種樂趣。
JavaScript高級程序設計學習(四)之引用類型