1

So for example, in Array.prototype.slice.call(arguments), call comes before slice but in var standard= name.substring(1).toLowerCase() substring is called before toLowerCase. Why is there this difference and how do I know which order functions are called in when you chain them?

user2864740
  • 54,112
  • 10
  • 112
  • 187
slynthin
  • 65
  • 3
  • 1
    `call` calls the function `slice`. There's only one function call there. – elclanrs Aug 15 '14 at 02:13
  • Learn about [call and apply](http://stackoverflow.com/questions/1986896/what-is-the-difference-between-call-and-apply) – Mathletics Aug 15 '14 at 02:15
  • but isn't call a prototype of function? And slice is a prototype of array, and substring is a prototype and toLowerCase is a prototype – slynthin Aug 15 '14 at 02:16
  • the function 'slice' is being borrowed from prototype and being called on the object in arguments. There's no chaining of functions like in your substring example. – robotcookies Aug 15 '14 at 02:17
  • Sort of. Again, go learn what `call` does and the answer will be clear. – Mathletics Aug 15 '14 at 02:17
  • 1
    Function execution in javascript is done with parenthesis. You are comparing apples with oranges. The first line executes one function (call), the second executes two (substring and then toLowerCase) – OJay Aug 15 '14 at 02:18

3 Answers3

1

I think you misunderstands something... it is simply

Array.prototype.slice.call(arguments)

only invokes one function which is slice()

.call() invokes slice() function and .call() is a method of slice

so

call() calls the previous method with the provided context and arguments. which makes its right to left until only the previous function before call()

and with regards to chaining

Chaining simply means that you use the return value of a function you invoke and that value is an object that contains a method you invoke again. so it happens from left to right

the best example is

var firststr = "my house".substring(2); //then this returns a string
var secondstr = firststr.trim(); //method call trim() on the return of .substring()

that can be rewritten as

"my house".substring(2).trim();

MUST READ:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call

Community
  • 1
  • 1
Netorica
  • 16,405
  • 16
  • 70
  • 105
  • but why isn't it something like Array.prototype.call(arguments).slice? – slynthin Aug 15 '14 at 02:18
  • 2
    @slynthin because that doesn't make any sense. Seriously, go [read about call](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) to understand why what you're asking is nonsense. `call` says "call the previous method with the provided context and arguments." It's not chaining. – Mathletics Aug 15 '14 at 02:19
0

In your example, prototype and slice are properties of the Array object:

Array.prototype.slice  // On the Array.prototype object, get `.slice` property

Then, with the .slice property, get the property .call on it and execute that. In this example, only .call() is a method invocation (e.g. a function call). This is not chaining at all. This is just nested property declarations, not chaining.

Chaining like your other example:

var standard = name.substring(1).toLowerCase()

executes left to right. name.substring(1) is executed and on the return result from that method, the .toLowerCase() method is called. Chaining only works if the prior methods return appropriate object types for the follow-on methods. In this case, a new string object is returned by name.substring(1) and .toLowerCase() is called on that new string object. Thus things execute from left to right.

jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • okay, I guess I'm just confused because MDN defined call/slice/substring/toLowerCase as all prototypes, so in my mind I think of them as under the same category so I expect all of them to read in one direction – slynthin Aug 15 '14 at 02:20
  • @slynthin - It is slightly confusing. They are methods on a prototype and can be referenced on objects of that type. One uses `Array.prototype.slice` only when you don't already have the appropriate array to call `.slice()` on. If you had an array already, you would just call `array.slice()` and not need to specify the prototype. Then, `.slice` is an instantiated function object which has `.call()` on it's prototype so you can do `slice.call()`. – jfriend00 Aug 15 '14 at 02:23
  • `call` is a method on the `Function` prototype. `slice` is on `String/Array` and `substring/toLowerCase` are on `String`. You are conflating prototypal inheritance, method invocation, nested lookups, and chaining into one mess of confusion. – Mathletics Aug 15 '14 at 02:23
  • @slynthin - said a different way. When a function is defined on a prototype, that means you can get access to that function two ways. First, you can specify it on the prototype as in `Array.prototype.slice`. Second, it will automatically be available on any object of that type as in `var array = [1,2,3]; var x = array.slice(1);`. If a function is defined on an object's prototype, then MDN tells you which prototype it is defined on and thus which object type it is associated with. Other functions like `eval()` are not defined on a specific prototype as they are just globally available. – jfriend00 Aug 15 '14 at 02:27
0

slice is a property (which happens to be a function) of Array.prototype, and you're using call to invoke that function (that's one function call). name.substring(1).toLowerCase() chains the functions substring and toLowerCase (in that order).

celeritas
  • 1,963
  • 1
  • 14
  • 25