Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning apply to a variable

Anyone knows why in javascript this works

m = Math.max
m.apply(null, [1,2,3])

but this doesn't?

m = Math.max.apply
m(null, [1,2,3])

It throws the exception:

TypeError: Function.prototype.apply was called on undefined, which is a undefined and not a function

like image 789
Domajno Avatar asked Oct 04 '16 07:10

Domajno


2 Answers

As per the spec

  1. If IsCallable(func) is false, throw a TypeError exception.

func is the Object on which apply method is called upon.

apply lets you specify the context of the function later, which is undefined in your case since m doesn't have the Function context (which is supposed to be specified in the arguments).

Since arguments

Uncaught TypeError: Function.prototype.apply was called on undefined, which is a undefined and not a function

You can test this by trying the following

Example 1:

m = Math.max.apply.bind(this)
m(this, [1,2,3]) 

Uncaught TypeError: Function.prototype.apply was called on , which is a object and not a function

Example 2:

m = Math.max.apply.bind(null)
m(this, [1,2,3])

Uncaught TypeError: Function.prototype.apply was called on null, which is a object and not a function

Example 3: (This one doesn't give error since function context is specified)

m = Math.max.apply.bind(function(){})
m(this, [1,2,3])

undefined

Example 4: (Finally this gives you output you want)

m = Math.max.apply.bind(Math.max)
m(this, [1,2,3])

3

like image 148
gurvinder372 Avatar answered Sep 28 '22 04:09

gurvinder372


To understand why the second example fails you must understand about the function context in Javascript. In Javascript, methods are like messages sent to the object they are being called. The object they are called is their context, and therefore this object will be the value of this inside the function body.

apply is a special function which lets you set this context as the first argument, and then the rest of arguments will be the arguments of the function that is being applied Math.max in your example. But at the same time apply needs to be called on a function object to work. In the second example, you are storing in the m variable a reference to the apply function, and you are calling it without context, so it fails because apply doesn't know which function it has to call.

like image 29
jorgonor Avatar answered Sep 28 '22 06:09

jorgonor