天天看點

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,原因很大程度因為風險不可控。對于項目而言,風險可控是個很重要的事情。

另外上述的代碼雖然是借鑒該書,但是我強烈建議朋友們,學習時或者看該篇文章時,還是要抱着“知行合一”的概念。每閱讀一小塊,加以實踐。這樣也不失為一種樂趣。