1. 程式人生 > >JavaScript高級程序設計學習(四)之引用類型

JavaScript高級程序設計學習(四)之引用類型

區別 function 起點 有時 () filter 例子 person 移除

在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高級程序設計學習(四)之引用類型