JavaScript: passing built-in objects' methods as callback functions -


i've been working through eloquent javascript's exercises , found out think odd. wrote trivial array-flattening piece of code:

var arrays = [[1, 2, 3], [4, 5], [6]]; var out = arrays.reduce(function(acc, next){ return acc.concat(next); }); console.log(out); // → [1, 2, 3, 4, 5, 6] 

so far good. didn't seem pretty me, rewrote as:

var arrays = [[1, 2, 3], [4, 5], [6]]; var my_concat = function(acc, next){ return acc.concat(next); } var out = arrays.reduce(my_concat); console.log(out); // → [1, 2, 3, 4, 5, 6] 

it better, need introduce function, anonymous or named, such basic thing? array.prototype.concat.call's call signature need! feeling smart, rewrote code again:

var arrays = [[1, 2, 3], [4, 5], [6]]; var out = arrays.reduce([].concat.call); // → typeerror: arrays.reduce not function (line 2) 

well, haven't turned out expected. error message seemed cryptic me.

i decided investigate. works:

var arrays = [[1, 2, 3], [4, 5], [6]]; var my_concat = function(acc, next){ return [].concat.call(acc,next); } var out = arrays.reduce(my_concat); console.log(out); // → [1, 2, 3, 4, 5, 6] 

and works:

var arrays = [[1, 2, 3], [4, 5], [6]]; arrays.my_concat = function(acc, next) { return [].concat.call(acc, next); } var out = arrays.reduce(arrays.my_concat); console.log(out); // → [1, 2, 3, 4, 5, 6] 

more tinkering in console:

[].concat.call // → call() { [native code] } typeof [].concat.call // → "function" [].concat.call([1, 2, 3], [4, 5]) // → [1, 2, 3, 4, 5] var cc = [].concat.call cc // → call() { [native code] } typeof cc // → "function" cc([1, 2, 3], [4, 5]) // → uncaught typeerror: cc not function(…) 

and works:

array.prototype.my_concat = function(acc, next) { return [].concat.call(acc, next); } // → function (acc, next) { return [].concat.call(acc, next); } [[1, 2, 3], [4, 5], [6]].reduce([].my_concat) // → [1, 2, 3, 4, 5, 6] [[1, 2, 3], [4, 5], [6]].reduce([].concat.call) // → uncaught typeerror: [[1,2,3],[4,5],[6]].reduce not function(…) 

is there special built-in functions .call?

call method functions inherit function.prototype. is,

arrays.reduce.call === function.prototype.call 

the call method knows function want call because function passed this value.

when pass call callback, called passing undefined this value. since undefined not function, throws. on firefox error:

typeerror: function.prototype.call called on incompatible undefined 

instead, try 1 of these callbacks

function.call.bind([].concat); [].concat.bind([]); 

however, problem won't work properly, because callback called 4 arguments, not 2:

  • previousvalue
  • currentvalue
  • currentindex
  • array

you want rid of last two, need custom function anyways.

however, these not approaches. each time call concat, creates new array. therefore, if want flatten array, should call concat once instead of per each item in array:

[].concat.apply([], arrays); // works 

Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -