-4

MY question is simple but I just don't know if im missing something.

Why Arr prototype slice call is even needed?

why its even needed since you can run the function just assigning arguments to the args variable. I'm aware that its an array-like but it doesn't have the methods from it

Why arguments === func is false?

how func.apply(null, args) works?

function logAndReturn(func) {  
  return function() {  
    var args = Array.prototype.slice.call(arguments);
    var result = func.apply(null, args);
    console.log('Result', result);
    return result;
  }
}
var addAndLog = logAndReturn(add);
Etez
  • 3
  • 4
  • 3
    Possible duplicate of [how does Array.prototype.slice.call() work?](http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work) – Sebastian Simon Aug 01 '16 at 23:21
  • also, `arguments` is not an array – Jaromanda X Aug 01 '16 at 23:21
  • 1
    The other question is a dupe of [What does this usage of `apply()` mean in JavaScript?](http://stackoverflow.com/q/10607760/4642212). Don’t include multiple questions per post and research more in the future. – Sebastian Simon Aug 01 '16 at 23:24
  • @JaromandaX Who said `arguments` was an `Array`? Or are you just trying to clarify that that’s the reason for the necessity of `slice`? – Sebastian Simon Aug 01 '16 at 23:26
  • @Xufox - yes, I was clarifying the reason for using `[].slice.call` – Jaromanda X Aug 01 '16 at 23:27
  • @JaromandaX But it dont quite tell why its even needed since you can run the function just asigning argments to the args variable. I'm aware that its an array-like but it doesnt have the methods from it – Etez Aug 01 '16 at 23:31
  • `why its even needed`. Depends on what you want to do with `arguments` - not going to go through every use case to explain when it's needed and when it isn't ... if you need `arguments` to be an array, you need to "convert" `arguments` to an array somehow – Jaromanda X Aug 01 '16 at 23:35
  • It's not needed in the example as `func.apply(null, arguments)` works, but its usually done when you need to take away arguments or add. In ES6 you do it much simpler: `(...arg) => func(curry, ...arg)` – Sylwester Aug 02 '16 at 00:16
  • @Xufox if you're referencing the same `arguments` the OP used in his/her code (on line 3), `arguments[0]` is not equal to `func`. You should delete your comment. – Mulan Aug 02 '16 at 16:32

1 Answers1

0

You're asking a lot of questions, most of which are duplicates. However, I know it can sometimes be hard to piece together many different answers to find the answer to your own question. In the future, you should avoid asking more than on question in a post. It will make some people less angry.

I'll add some comments to the code inline

function logAndReturn(func) { // <------------┐ 
  return function() { // <------------------┐ |
    // `arguments` belongs to this function-┘ |
    // NOT this one --------------------------┘
    var args = Array.prototype.slice.call(arguments);

    // `apply` expects an array but `arguments` is an object
    // we call `slice` on `arguments` so that it can be converted to an array
    var result = func.apply(null, args);

    console.log('Result', result);
    return result;
  }
}
var addAndLog = logAndReturn(add);

In reality, JavaScript is a lot more forgiving than this tho. It's not a typed language, so I kind of lied when I said apply expects an Array. Sure, it'd be nice, but it's also not going to cry if you give it an array-like object

function theHiddenTruthBehindArguments() {
  console.log(arguments)
  console.log(arguments.length)
}

theHiddenTruthBehindArguments(0,1,'abc')
// {"0":0,"1":1,"2":"abc"}
// 3

arguments is actually an array-like object. It has sequential numerical keys (beginning with 0) and a length property which is all the information required to treat any object like an array.

So this would actually work

function logAndReturn(func) {
  return function() {
    // this works too !
    var result = func.apply(null, arguments);
    console.log('Result', result);
    return result;
  }
}
var addAndLog = logAndReturn(add);

And to answer your last question, apply woks in a pretty simple way …

let args = [1,3,4]
func.apply(null, args)

… is (mostly) the same thing as …

func(1,3,4)

This one you can read the dupe question for. There a couple details you might need to know.


That function you gave can be expressed better in ES6 and I think it'd be a lot less confusing for you

function logAndReturn(func) {

  // rest parameter ...args is the new way to express variadic functions
  // (functions that take a variable number of arguments)
  // all arguments given will be collected in a single `args` array
  return function(...args) {

    // spread syntax will expand the array to call `func`
    // with all of the collected args
    var result = func(...args)

    console.log('Result', result)
    return result
  }
}
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • `apply` works well with `arguments` directly so the `splice` serves no purpose. [The documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) clearly states it takes any array like objects of which the `arguments` variable is – Sylwester Aug 02 '16 at 16:21
  • @Sylwester thanks, I was just getting around to updating that. Sometimes the most elementary questions can be the hardest to answer, eh ? – Mulan Aug 02 '16 at 16:26
  • @Sylwester now I'm curious where the `slice.call(arguments)` pattern came from. Was there ever a time in ES history when `f.apply(null, arguments)` would not have worked without an actual Array object? – Mulan Aug 02 '16 at 16:31
  • You are right. Before ES5 it needed to be an Array. – Sylwester Aug 02 '16 at 16:48
  • @Sylwester thanks. I wouldn't have known how to find that information ^_^ – Mulan Aug 02 '16 at 17:50
  • @naomik Yes, it made me understand a lot more in the ES6 syntax I was aware of the spread operator but I didn't now that it was similar to it. I want to abuse you one more time just to clear this a bit more why is that the parameter(args) in the returned functions have the parameters of the functions argument (func) ? if its too annoying i would understand if you skip this I will be anyway really thankful for you and really sorry(to everyone i insulted) my questions were dumb. – Etez Aug 03 '16 at 04:15
  • @Etez I'm happy to help. I'm not the kind to get insulted, but I know some people are sensitive on the matter. Just trying to help you out in the future. Can you reword your question a little bit? I'm having trouble understanding what you mean. – Mulan Aug 03 '16 at 05:16
  • How is that the returning function aka "return function(...args) {" receives the arguments of the passed in function. `logAndReturn(add(1, 2))` how is that this `return function(...args) {` function gets [1, 2] parameters from the passed in function in this case `add()` Sorry if i'm confusing you >. – Etez Aug 04 '16 at 02:31
  • @Etez, I'll get you an explanation in a little bit. I'm just a little preoccupied at the moment. Hang in there, buddie. – Mulan Aug 04 '16 at 03:57