Dojo1.11官方教程文檔翻譯(4.2)數組

原文地址:https://dojotoolkit.org/documentation/tutorials/1.10/arrays/index.html
本翻譯項目放在GitBook上,歡迎參與。
GitBook地址:https://www.gitbook.com/book/limeng1900/dojo1-11-tutorials-translation-in-chinese/details
轉載請註明出處:http://blog.csdn.net/taijiedi13/ – 碎夢道


在本教程中,你將瞭解Dojo針對JavaScript數組的跨平臺解決方案:dojo/_base/array

入門

數據存取和操作是你的web應用開發時非常重要的部分。JavaScript的實現者們瞭解這些,所以爲了更加易用,他們在數組實例上加入了一些方法。可惜,不是所有的瀏覽器和環境都採取這些新方法。好消息是Dojo爲這些數組新方法提供輔助方法,因此無論你在什麼環境下運行,你都可以輕易駕馭數組。

查找

你在用數組的時候會需要的一項操作是找到數組的某一項。Dojo在dojo/_base/array資源裏提供兩個函數:indexOflastIndexOfindexOf 方法從數組的最小索引查找到最大索引,lastIndexOf則從大到小。它們接收同樣的參數:查找的數組、查找的項、開始查找的索引(可選)。來看一些例子:

require(["dojo/_base/array"], function(arrayUtil) {
    var arr1 = [1,2,3,4,3,2,1,2,3,4,3,2,1];
    arrayUtil.indexOf(arr1, 2); // returns 1
    arrayUtil.indexOf(arr1, 2, 2); // returns 5
    arrayUtil.lastIndexOf(arr1, 2); // returns 11
});

如果沒找到該項,兩個函數都返回-1。需要注意的是,兩個函數都使用嚴格比較(===),所以你能找到的不僅僅是原始值:

var obj1 = { id: 1 },
    arr2 = [{ id: 0 }, obj1, { id: 2 }, { id: 3 }];

// This search returns 1, as obj1 is the second item
// in the array.
arrayUtil.indexOf(arr2, obj1);

// This search returns -1. While the objects may look similar,
// they are entirely different objects, and so this object
// isn't found in the array.
arrayUtil.indexOf(arr2, { id: 1 });

View Demo

循環

另一個常用操作是循環遍歷數組的每一項。通常,會類似下面這樣:

var item;
for(var i = 0; i < arr.length; i++){
    item = arr[i];
    // do something with item
}

上面這樣做的缺點是當你在一個事件處理器裏訪問item時,它可能不是你想要的項,而是所有事件處理器數組的最後一項。forEach給了我們一個設置循環的標準方式,同時在作用域鏈查找期間也會保留項目。Array.prototype.forEach有兩個異常:

  • 如果你的索引之中存在未定義的索引,它也會進行迭代。就是說如果你的數組裏有一個undefined值,它依然會對那個索引執行你的函數,而不能跳過它。
  • 循環是執行在數組本身的。而當在支持的瀏覽器裏使用原生forEach方法時,它會遍歷數組的一個副本而不是數組本身。你在函數裏對原始數組做的任何改變在隨後的函數執行的都能看到。

實際上,這兩點差異適用於本教程中討論的所有方法。我們來看一個例子:

var arr = ["one", "two", "three", "four"],
    // dom is from dojo/dom
    list1 = dom.byId("list1");

// Skip over index 4, leaving it undefined
arr[5] = "six";

arrayUtil.forEach(arr, function(item, index){
    // This function is called for every item in the array
    if(index == 3){
        // this changes the original array,
        // which changes the item passed to
        // the sixth invocation of this function
        arr[5] = "seven";
    }

    // domConstruct is available at dojo/dom-construct
    domConstruct.create("li", {
        innerHTML: item + " (" + index + ")"
    }, list1);
});

arrayUtil.forEach方法接收三個參數:一個用來迭代的數組、一個爲數組每一項(包含已定義之間存在的未定義索引)調用的函數(或者回調)、一個對象(可選)用作調用回調的作用域。
你提供的回調將調用給數組的每一個索引直到最後分配的索引(包含在內),它接收三個參數:當前索引的對象或值、當前索引本身、要遍歷的數組的引用。回調也將在arrayUtil.forEach第三個參數的作用域裏調用,如果沒提供第三個參數則爲全局對象(瀏覽器下爲window)。來看下作用域參數:

var list2 = dom.byId("list2"),
    myObject = {
        prefix: "ITEM: ",
        formatItem: function(item, index){
            return this.prefix + item + " (" + index + ")";
        },
        outputItems: function(arr, node){
            arrayUtil.forEach(arr, function(item, index){
                domConstruct.create("li", {
                    innerHTML: this.formatItem(item, index)
                }, node);
            }, this);
        }
    };

myObject.outputItems(arr, list2);

這可能是作用域參數最常用的模式:傳遞this以便於回調函數將在調用它的方法的作用域裏調用。當你使用widget時,這個模式非常有用,建議保存起來以備後用。

View Demo

操作

Dojo讓循環變的很簡單,不過你就會經常想要獲得一個數組的數據,然後用它來做一些事再得到一個新數組。比如我們有一個字符串數組,想要將轉換成對象,並將對象的“name”屬性設爲字符串的值。我們可能這麼做:

var original = ["one", "two", "three", "four", "five"],
    transformed = [];

arrayUtil.forEach(original, function(item, index){
    transformed.push({
        id: index * 100,
        text: item
    });
}); // [ { id: 0, text: "one" }, { id: 100, text: "two" }, ... ]

這沒什麼錯誤,不過新版的JavaScript和Dojo有一個相當的功能:arrayUtil.map。我們來看看:

var mapped = arrayUtil.map(original, function(item, index){
    return {
        id: index * 100,
        text: item
    };
}); // [ { id: 0, text: "one" }, { id: 100, text: "two" }, ... ]

map的參數和forEach一樣。不同點在於返回值會被存儲在一個新數組裏,它的索引和原始數組一樣。從map返回了新的數組。
Dojo覆蓋新版JavaScript的另一個常見轉換是filterfilter的想法是你有一個數組指向選擇其中一些符合條件的項。用forEach也可以實現,不過filter更簡單。
參數相比map還是沒有改變,不過在filter裏,會評估回調返回的值,如果爲真則將該項附加到filter返回的數組裏。讓我們看另一個例子:

var filtered = arrayUtil.filter(mapped, function(item, index){
    return item.id > 50 && item.id < 350;
}); // [ { id: 100, text: "two" }, { id: 200, text: "three" },
    //   { id: 300, text: "four" } ]

View Demo

匹配

有時候你想知道一個數組的項是否能匹配一定的條件:或許你想知道一些對象是否有一個error屬性,或者你想確認所有的對象有一個text屬性。這就是someevery的用處了。它們的函數簽名很像filter(包括回調的返回),不過不是返回一個數組,而是一個布爾值:如果數組每一項的回調都返回trueevery返回true,如果數組至少有一項的回調返回truesome返回true。下面的例子應該能解釋地更清楚:

var arr1 = [1,2,3,4,5],
    arr2 = [1,1,1,1,1];

arrayUtil.every(arr1, function(item){ return item == 1; }); // returns false
arrayUtil.some(arr1, function(item){ return item == 1; });  // returns true

arrayUtil.every(arr2, function(item){ return item == 1; }); // returns true
arrayUtil.some(arr2, function(item){ return item == 1; });  // returns true

arrayUtil.every(arr2, function(item){ return item == 2; }); // returns false
arrayUtil.some(arr2, function(item){ return item == 2; });  // returns false

簡單的理解就是every就像是在if聲明裏用的&&som就像是||

View Demo

小結

JavaScript規範已經提供了一些強大的數組方法,但不是所有的瀏覽器和環境都支持。Dojo的dojo/_base/array模塊在數組的新舊方法之間搭起橋樑,讓你可以用更少的代碼更快、更高效的做更多的事。

發佈了25 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章