'Array.push return pushed value?

Are there any substantial reasons why modifying Array.push() to return the object pushed rather than the length of the new array might be a bad idea?

I don't know if this has already been proposed or asked before; Google searches returned only a myriad number of questions related to the current functionality of Array.push().

Here's an example implementation of this functionality, feel free to correct it:

;(function() {
    var _push = Array.prototype.push;
    Array.prototype.push = function() {
        return this[_push.apply(this, arguments) - 1];
    }
}());

You would then be able to do something like this:

var someArray = [],
    value = "hello world";

function someFunction(value, obj) {
    obj["someKey"] = value;
}

someFunction(value, someArray.push({}));

Where someFunction modifies the object passed in as the second parameter, for example. Now the contents of someArray are [{"someKey": "hello world"}].

Are there any drawbacks to this approach?



Solution 1:[1]

Are there any substantial reasons why modifying Array.push() to return the object pushed rather than the length of the new array might be a bad idea?

Of course there is one: Other code will expect Array::push to behave as defined in the specification, i.e. to return the new length. And other developers will find your code incomprehensible if you did redefine builtin functions to behave unexpectedly.

At least choose a different name for the method.

You would then be able to do something like this: someFunction(value, someArray.push({}));

Uh, what? Yeah, my second point already strikes :-)

However, even if you didn't use push this does not get across what you want to do. The composition that you should express is "add an object which consist of a key and a value to an array". With a more functional style, let someFunction return this object, and you can write

var someArray = [],
    value = "hello world";

function someFunction(value, obj) {
    obj["someKey"] = value;
    return obj;
}

someArray.push(someFunction(value, {}));

Solution 2:[2]

See my detailed answer here

TLDR;
You can get the return value of the mutated array, when you instead add an element using array.concat[].

concat is a way of "adding" or "joining" two arrays together. The awesome thing about this method, is that it has a return value of the resultant array, so it can be chained.

newArray = oldArray.concat[newItem];

This also allows you to chain functions together

updatedArray = oldArray.filter((item) => { item.id !== updatedItem.id).concat[updatedItem]};

Where item = {id: someID, value: someUpdatedValue}

The main thing to notice is, that you need to pass an array to concat.
So make sure that you put your value to be "pushed" inside a couple of square brackets, and you're good to go.
This will give you the functionality you expected from push()

You can use the + operator to "add" two arrays together, or by passing the arrays to join as parameters to concat().

let arrayAB = arrayA + arrayB;
let arrayCD = concat(arrayC, arrayD);

Note that by using the concat method, you can take advantage of "chaining" commands before and after concat.

Solution 3:[3]

Just as a historical note -- There was an older version of JavaScript -- JavaScript version 1.2 -- that handled a number of array functions quite differently.

In particular to this question, Array.push did return the item, not the length of the array.

That said, 1.2 has been not been used for decades now -- but some very old references might still refer to this behavior.

http://web.archive.org/web/20010408055419/developer.netscape.com/docs/manuals/communicator/jsguide/js1_2.htm

Solution 4:[4]

By the coming of ES6, it is recommended to extend array class in the proper way , then , override push method :

class XArray extends Array {
   
   push() {
     super.push(...arguments);
     return (arguments.length === 1) ? arguments[0] : arguments;
   }
 
}
//---- Application
let list  = [1, 3, 7,5];

list = new XArray(...list);

console.log(
  'Push one item : ',list.push(4)
);

console.log(
  'Push multi-items :', list.push(-9, 2)
);

console.log(
   'Check length :' , list.length
)

Solution 5:[5]

var arr = [];
var element = Math.random();
assert(element === arr[arr.push(element)-1]);

Solution 6:[6]

Method push() returns the last element added, which makes it very inconvenient when creating short functions/reducers. Also, push() - is a rather archaic stuff in JS. On ahother hand we have spread operator [...] which is faster and does what you needs: it exactly returns an array.

// to concat arrays
const a = [1,2,3];
const b = [...a, 4, 5];
console.log(b) // [1, 2, 3, 4, 5];

// to concat and get a length
const arrA = [1,2,3,4,5];
const arrB = [6,7,8];
console.log([0, ...arrA, ...arrB, 9].length); // 10

// to reduce
const arr = ["red", "green", "blue"];
const liArr = arr.reduce( (acc,cur) => [...acc, `<li style='color:${cur}'>${cur}</li>`],[]);
console.log(liArr);
  //[ "<li style='color:red'>red</li>", 
  //"<li style='color:green'>green</li>", 
  //"<li style='color:blue'>blue</li>" ]

Solution 7:[7]

How about doing someArray[someArray.length]={} instead of someArray.push({})? The value of an assignment is the value being assigned.

var someArray = [],
    value = "hello world";

function someFunction(value, obj) {
    obj["someKey"] = value;
}

someFunction(value, someArray[someArray.length]={});

console.log(someArray)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Jeremy J Starcher
Solution 4 Abdennour TOUMI
Solution 5 brillout
Solution 6
Solution 7 loop