JavaScript配列オブジェクトの原型方法(二)

7503 ワード

Aray.prototype.sort(compreFunction)
  • デフォルトの並べ替え順序は、文字列Unicodeコードポイントによるものです.
  • は、配列の要素を適切な位置で並べ替える
  • .
  • は、並べ替えられた行列を返します.元の配列はすでに並べ替えられています.
  • の代わりに配列されています.
    パラメータ
  • [compreFunction]
  • compreFunctionが指定されていない場合、要素は変換された文字列の各文字のUnicodeの位置に従って並べ替えられます.例えば「Banana」は「cherry」の前に並べられます.数字は大きい時より9は80前に現れますが、ここで比較すると数字は先に文字列に変換されますので、「80」は「9」より前にします.
    compreFunctionが指定されている場合、その関数を呼び出した戻り値に従って配列が並べられます.つまり、aとbは2つの比較される要素である.
  • compreFunction(a,b)が0より小さい場合、aはbの前に配置される.
  • compreFunction(a,b)が0に等しい場合、aおよびbの相対的な位置は不変である(ブラウザの影響で変わる可能性がある)
  • .
  • compreFunction(a,b)が0より大きい場合、bはaの前に配置される.
  • compreFunction(a,b)は、常に同じ入力に対して同じ比較結果を返さなければならない.そうでないと、並べ替えの結果は不確定となる.
  • 例1
    var fruit = ['cherries', 'apples', 'bananas'];
    fruit.sort(); 
    // ['apples', 'bananas', 'cherries']
    
    var scores = [1, 10, 21, 2]; 
    scores.sort(); 
    // [1, 10, 2, 21]
    //   10 2  ,
    //     Unicode      "10" "2"  
    
    var things = ['word', 'Word', '1 Word', '2 Words'];
    things.sort(); 
    // ['1 Word', '2 Words', 'Word', 'word']
    //  Unicode ,          ,
    //            .
    
    例2
    var numbers = [4, 2, 5, 1, 3];
    numbers.sort(function(a, b) {
      return a - b;
    });
    console.log(numbers);
    // [1, 2, 3, 4, 5]
    
    例3
    var items = [
      { name: 'Edward', value: 21 },
      { name: 'Sharpe', value: 37 },
      { name: 'And', value: 45 },
      { name: 'The', value: -12 },
      { name: 'Magnetic' },
      { name: 'Zeros', value: 37 }
    ];
    items.sort(function (a, b) {
      if (a.value > b.value) {
        return 1;
      }
      if (a.value < b.value) {
        return -1;
      }
      // a      b
      return 0;
    });
    
    name:'magnetic'、{name:'Zeros',value:37}この二つのデータはデータ比較ができないので、順番は変わりません.
    Aray.prototype.includes(search Element、from Index)
  • は、1つの配列が指定された値
  • を含むかどうかを判断する.
  • 戻り値ブックタイプ
  • パラメータを携帯する
  • [search Element]が表示される要素値
  • [from Index](オプション)は、インデックスからsearch Elementを検索し始める.負の値であれば、array.length+from Indexのインデックスで検索を開始します.from Indexはデフォルトで0です.
  • 例1
    [1, 2, 3].includes(2);     // true
    [1, 2, 3].includes(4);     // false
    [1, 2, 3].includes(3, 3);  // false
    [1, 2, 3].includes(3, -1); // true
    [1, 2, NaN].includes(NaN); // true
    
    Froom Indexが配列長より大きい場合はfalseに戻り、クラス配列オブジェクトなどの表示が可能になります.
    例2
    (function() {
      console.log([].includes.call(arguments, 'a')); // true
      console.log([].includes.call(arguments, 'd')); // false
    })('a','b','c');
    
    es 5プロトタイプ拡張
    // https://tc39.github.io/ecma262/#sec-array.prototype.includes
    if (!Array.prototype.includes) {
      Object.defineProperty(Array.prototype, 'includes', {
        value: function(searchElement, fromIndex) {
    
          // 1. Let O be ? ToObject(this value).
          if (this == null) {
            throw new TypeError('"this" is null or not defined');
          }
    
          var o = Object(this);
    
          // 2. Let len be ? ToLength(? Get(O, "length")).
          var len = o.length >>> 0;
    
          // 3. If len is 0, return false.
          if (len === 0) {
            return false;
          }
    
          // 4. Let n be ? ToInteger(fromIndex).
          //    (If fromIndex is undefined, this step produces the value 0.)
          var n = fromIndex | 0;
    
          // 5. If n ≥ 0, then
          //  a. Let k be n.
          // 6. Else n < 0,
          //  a. Let k be len + n.
          //  b. If k < 0, let k be 0.
          var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
    
          // 7. Repeat, while k < len
          while (k < len) {
            // a. Let elementK be the result of ? Get(O, ! ToString(k)).
            // b. If SameValueZero(searchElement, elementK) is true, return true.
            // c. Increase k by 1.
            // NOTE: === provides the correct "SameValueZero" comparison needed here.
            if (o[k] === searchElement) {
              return true;
            }
            k++;
          }
    
          // 8. Return false
          return false;
        }
      });
    }
    
    Aray.prototype.map(calback,thisArg)
  • 次元配列の構造および値データ値は不変であり、一次元データの値がオブジェクトタイプである場合、calbackはそのオブジェクトを変更し、元の配列値オブジェクトタイプは変化する.例2
  • のように
  • は、各要素が供給された関数を呼び出して返される新しい配列を作成します.
  • calback関数は、値のあるインデックスだけで呼び出されます.与えられたことのない値やdeleteで削除されたインデックスは、
  • に呼び出されません.
    例1
    var a = [1,3,5,7,9];
    var c = a.map((item)=>{
      return item*2;
    })
    console.log(a);  // [1, 3, 5, 7, 9]
    console.log(c);  // [2, 6, 10, 14, 18]
    
    例2
    var e = [{a:1},{b:2},3];
    var f = e.map( (item)=>{
      if(typeof(item)=="number"){
        return item*3;
      }else{
        item.a = "a";
      }
      return item;
    } )
    console.log(e);  // [{a:"a"},{b:2},3];
    console.log(f);   //  [{a:"a"},{b:2},9];
    
    パラメータ
  • [calback(value,index,arr)]コールバック関数
  • [value]現在の要素
  • [index]現在の要素インデックス
  • [arr]map方法で呼び出された配列
  • [thisArg](オプション)によりcalback関数を実行する際に使用するthis値.
  • 特殊な例
    //             String    map                  ASCII       
    
    var a = Array.prototype.map.call("Hello World", function(x) { 
      return x.charCodeAt(0); 
    })
    // a   [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
    
    var elems = document.querySelectorAll('select option:checked');
    var values = Array.prototype.map.call(elems, function(obj) {
      return obj.value;
    });
    
    
    クラシックケース
    //           :
    ["1", "2", "3"].map(parseInt);
    //        [1, 2, 3]
    //         [1, NaN, NaN]
    
    //     parseInt ,         .
    //     ,parseInt       .         .
    //       "alert(parseInt.length)===2"   .
    // map     callback   ,         :         , 
    //     ,      .
    //      parseInt   ,         ,    ,
    // parseInt                .     NaN.
    
    function returnInt(element) {
      return parseInt(element, 10);
    }
    
    ['1', '2', '3'].map(returnInt); // [1, 2, 3]
    //        
    
    //             ,    
    ['1', '2', '3'].map( str => parseInt(str) );
    
    //         :
    ['1', '2', '3'].map(Number); // [1, 2, 3]
    //  `parseInt`   ,              :
    ['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
    
    互換性のある環境
    //    ECMA-262, Edition 5, 15.4.4.19
    //   : http://es5.github.com/#x15.4.4.19
    if (!Array.prototype.map) {
      Array.prototype.map = function(callback, thisArg) {
    
        var T, A, k;
    
        if (this == null) {
          throw new TypeError(" this is null or not defined");
        }
    
        // 1.  O     map     .
        var O = Object(this);
    
        // 2. len     O   .
        var len = O.length >>> 0;
    
        // 3.  callback    ,   TypeError  .
        if (Object.prototype.toString.call(callback) != "[object Function]") {
          throw new TypeError(callback + " is not a function");
        }
    
        // 4.     thisArg  ,  T   thisArg;  T undefined.
        if (thisArg) {
          T = thisArg;
        }
    
        // 5.      A,      O  len
        A = new Array(len);
    
        // 6.  k   0
        k = 0;
    
        // 7.   k < len  ,    .
        while(k < len) {
    
          var kValue, mappedValue;
    
          //  O,k      
          if (k in O) {
    
            //kValue   k    .
            kValue = O[ k ];
    
            //   callback,this  T,     .   kValue: ,k:  ,O:   .
            mappedValue = callback.call(T, kValue, k, O);
    
            //          A .
            A[ k ] = mappedValue;
          }
          // k  1
          k++;
        }
    
        // 8.      A
        return A;
      };      
    }