官术网_书友最值得收藏!

Manipulating arrays in the ES5 way

Some years ago when the support of ES5 features was poor (EcmaScript 5th edition was finalized in 2009), libraries such as Underscore and Lo-Dash got highly popular as they provided a comprehensive set of utilities to deal with arrays/collections. Today, many developers still use third-party libraries (including jQuery/Zepro) for methods such as map, filter, every, some, reduce, and indexOf, while these are available in the native form of JavaScript. It still depends on how you use such libraries, but it may likely happen that you don't need them anymore. Let's see what we have now in JavaScript.

Array methods in ES5

Array.prototype.forEach is probably the most used method of the arrays. That is, it is the native implementation of _.each, or for example, of the $.each utilities. As parameters, forEach expects an iteratee callback function and optionally a context in which you want to execute the callback. It passes to the callback function an element value, an index, and the entire array. The same parameter syntax is used for most array manipulation methods. Note that jQuery's $.each has the inverted callback parameters order:

"use strict";
var data = [ "bar", "foo", "baz", "qux" ];
data.forEach(function( val, inx ){
  console.log( val, inx ); 
});

Array.prototype.map produces a new array by transforming the elements of a given array:

"use strict";
var data = { bar: "bar bar", foo: "foo foo" },
   // convert key-value array into url-encoded string
   urlEncStr = Object.keys( data ).map(function( key ){
     return key + "=" + window.encodeURIComponent( data[ key ] );
   }).join( "&" );

console.log( urlEncStr ); // bar=bar%20bar&foo=foo%20foo

Array.prototype.filter returns an array, which consists of given array values that meet the callback's condition:

"use strict";
var data = [ "bar", "foo", "", 0 ],
   // remove all falsy elements
   filtered = data.filter(function( item ){
     return !!item;
   });

console.log( filtered ); // ["bar", "foo"]

Array.prototype.reduce/Array.prototype.reduceRight retrieves the product of values in an array. The method expects a callback function and optionally the initial value as arguments. The callback function receive four parameters: the accumulative value, current one, index and original array. So we can, for an instance, increment the accumulative value by the current one (return acc += cur;) and, thus, we will get the sum of array values.

Besides calculating with these methods, we can concatenate string values or arrays:

"use strict";
var data = [[ 0, 1 ], [ 2, 3 ], [ 4, 5 ]],
   arr = data.reduce(function( prev, cur ) {
     return prev.concat( cur );
   }),
   arrReverse = data.reduceRight(function( prev, cur ) {
     return prev.concat( cur );
   });

console.log( arr ); //  [0, 1, 2, 3, 4, 5]
console.log( arrReverse ); // [4, 5, 2, 3, 0, 1]

Array.prototype.some tests whether any (or some) values of a given array meet the callback condition:

"use strict";
var bar = [ "bar", "baz", "qux" ],
   foo = [ "foo", "baz", "qux" ],
   /**
    * Check if a given context (this) contains the value
    * @param {*} val
    * @return {Boolean}
    */
   compare = function( val ){
     return this.indexOf( val ) !== -1; 
   };

console.log( bar.some( compare, foo ) ); // true

In this example, we checked whether any of the bar array values are available in the foo array. For testability, we need to pass a reference of the foo array into the callback. Here we inject it as context. If we need to pass more references, we would push them in a key-value object.

As you probably noticed, we used in this example Array.prototype.indexOf. The method works the same as String.prototype.indexOf. This returns an index of the match found or -1.

Array.prototype.every tests whether every value of a given array meets the callback condition:

"use strict";
var bar = [ "bar", "baz" ],
   foo = [ "bar", "baz", "qux" ],
   /**
    * Check if a given context (this) contains the value
    * @param {*} val
    * @return {Boolean}
    */
   compare = function( val ){
     return this.indexOf( val ) !== -1; 
   };

console.log( bar.every( compare, foo ) ); // true

If you are still concerned about support for these methods in a legacy browser as old as IE6-7, you can simply shim them with https://github.com/es-shims/es5-shim.

Array methods in ES6

In ES6, we get just a few new methods that look rather like shortcuts over the existing functionality.

Array.prototype.fill populates an array with a given value, as follows:

"use strict";
var data = Array( 5 );
console.log( data.fill( "bar" ) ); // ["bar", "bar", "bar", "bar", "bar"]

Array.prototype.includes explicitly checks whether a given value exists in the array. Well, it is the same as arr.indexOf( val ) !== -1, as shown here:

"use strict";
var data = [ "bar", "foo", "baz", "qux" ];
console.log( data.includes( "foo" ) );

Array.prototype.find filters out a single value matching the callback condition. Again, it's what we can get with Array.prototype.filter. The only difference is that the filter method returns either an array or a null value. In this case, this returns a single element array, as follows:

"use strict";
var data = [ "bar", "fo", "baz", "qux" ],
   match = function( val ){
     return val.length < 3;
   };
console.log( data.find( match ) ); // fo
主站蜘蛛池模板: 曲阜市| 沙湾县| 金昌市| 长宁区| 吉木萨尔县| 延长县| 长宁县| 望城县| 法库县| 崇左市| 文登市| 南皮县| 滕州市| 高邮市| 沙河市| 内黄县| 青河县| 济南市| 皋兰县| 集安市| 天门市| 长春市| 睢宁县| 原平市| 衢州市| 东明县| 开封市| 若羌县| 洪洞县| 凉城县| 成安县| 托克逊县| 鱼台县| 元阳县| 巫山县| 赣榆县| 安义县| 句容市| 南陵县| 嘉鱼县| 横山县|