Why is call necessary in this Javascript example? - javascript

Here's the problem (called "Compose functions (T Combinator)" on codewars.com, in case you want to try it out in the original environment):
Let's make a function called compose that accepts a value as a parameter, as well as any number of functions as additional parameters.
The function will return the value that results from the first parameter being used as a parameter for all of the accepted function parameters in turn. If only a single parameter is passed in, return that parameter.
So:
var doubleTheValue = function(val) { return val * 2; }
var addOneToTheValue = function(val) { return val + 1; }
compose(5, doubleTheValue) // should === 10
compose(5, doubleTheValue, addOneToTheValue) // should === 11
Here was one of the possible solutions:
var compose = function(initialValue) {
var functions = Array.prototype.slice.call(arguments, 1);
return functions.reduce(function(previousResult, func){
return func.call(this, previousResult);
}, initialValue);
}
Why do we need to return func.call(this, previousResult) rather than just func(previousResult)? The latter only works in some cases. What will "this" default to without the call?

Why do we need to return func.call(this, previousResult) rather than just func(previousResult)?
We don't really. this is not the this value of the compose function (what the author probably intended), but of the reduce callback - where it is specified to be undefined.
What will "this" default to without the call?
undefined as well, see Why is "this" in an anonymous function undefined when using strict?.

In strict mode, this will be undefined since there is no calling context.
In non-strict Javascript it will be the global object (window in a browser).

Why do we need to return func.call(this, previousResult) rather than just func(previousResult)?
this defaults to our window.
Basically, we're giving it a secondary value in order to further our progression down the line.
If you were to call simply previousResult, the JS doesn't know where to look to find such a thing. Your are referencing the window if you don't call a prior parameter. This is very common in most OOP languages. You can't look for your value IN window without further defining that you want something IN window.
Essentially, we are just providing a bogus variable in order to get to the next step in the chain. You will see this a lot with Python and Ruby code.
The reason you set this is because this will equal the parent window, then you know you can find the next variable within that particular parameter.
Simple Example:
It's sort of like trying to call a variable in a different function. Just doesn't work without defining your scope first.

Related

JavaScript setting value to variable properties on a function call

I found that there are these two ways that a variable property value can be updated on a function call
Example 1:
function bar( arg ) {
return arg + 1;
}
var foo = {
num: 1
};
foo.num = bar( foo.num );
console.log( foo.num );
Example 2:
function bar( arg ) {
arg.num = arg.num + 1;
}
var foo = {
num: 1
};
bar( foo );
console.log( foo.num );
I want to know what are the proper naming convention for each of the method calls.
Also can anyone explain, how it is possible to update the original variable value inside a closed function operation as shown in example 2?
Primitive parameters (such as a number) are passed to functions by
value; the value is passed to the function, but if the function
changes the value of the parameter, this change is not reflected
globally or in the calling function.
If you pass an object (i.e. a non-primitive value, such as Array or a
user-defined object) as a parameter and the function changes the
object's properties, that change is visible outside the function.
Source : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
Well in javascript objects are passed by reference so when you pass a object to a function you're passing it's memory reference not a copy.
So when you update value in the function it updates the value at reference.
function bar(arg) {
arg.num = arg.num + 1;
}
var foo = {
num: 1
};
bar(foo);
console.log(foo.num);
When you pass a primitive value it is passed by value. It passes a copy of value so whatever changes you do in close function will not affect the original value.
function bar(arg) {
arg = arg + 1;
}
var foo = 1
bar(foo);
console.log(foo);
I want to know what are the proper naming convention for each of the methods.
There are no naming conventions for functions (I would only call them methods if they are directly associated to an object), except thar the name is camelCase. However there is a convention in functional programming that functions that return something are pure (they do not change anything, but just return something new, like your first function), and functions that return nothing are impure, they change something. Wether you strictly follow that pattern depends on your codingstyle, I follow that often but not always. It is also a bit harder in JS as JS is not typed.
also can anyone explain, how it is possible to update the original variable value inside a closed function operation as shown in example 2?
It is impossible. If you pass a number, it is passed as a value, you have no way to find out where that number belongs to. Thats a good thing as you can always keep track which function is able to mutate an object. bar(foo) is, bar(foo.num) is not.

Why would you pass 'null' to 'apply' or 'call'?

According to this JavaScript reference:
The value null is a JavaScript literal representing null or an "empty"
value, i.e. no object value is present. It is one of JavaScript's
primitive values.
function getMax(arr){
return Math.max.apply(null, arr);
}
Wouldn't explicitly passing the keyword this be clearer, or at least more readable? Then again, at this point I may not understand why you would use null.
Why would you pass 'null' to 'apply' or 'call'?
When there is no value you wish to specify for the this pointer inside the function and the function you're calling is not expecting a particular this value in order to function properly.
Wouldn't explicitly passing the keyword this be clearer? Or at least
more human readable. Then again at this point I may not understand why
you would use null.
In your specific case, probably the best thing to pass is the Math object:
function getMax(arr){
return Math.max.apply(Math, arr);
}
While it turns out that it doesn't matter what you pass as the first argument for Math.max.apply(...) (only because of the implementation specifics of Math.max()), passing Math sets the this pointer to the exact same thing that it would be set to when calling it normally like Math.max(1,2,3) so that is the safest option since you are best simulating a normal call to Math.max().
Why would you pass 'null' to 'apply' or 'call'?
Here are some more details... When using .call() or .apply(), null can be passed when you have no specific value that you want to set the this pointer to and you know that the function you are calling is not expecting this to have any specific value (e.g. it does not use this in its implementation).
Note: Using null with .apply() or .call() is only usually done with functions that are methods for namespace reasons only, not for object-oriented reasons. In other words, the function max() is a method on the Math object only because of namespacing reasons, not because the Math object has instance data that the method .max() needs to access.
If you were doing it this way:
function foo() {
this.multiplier = 1;
}
foo.prototype.setMultiplier = function(val) {
this.multiplier = val;
}
foo.prototype.weightNumbers = function() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += (arguments[i] * this.multiplier);
}
return sum / arguments.length;
}
var x = new foo();
x.setMultiplier(3);
var numbers = [1, 2, 3]
console.log(x.weightNumbers.apply(x, numbers));
When the method you are calling .apply() on needs to access instance data, then you MUST pass the appropriate object as the first argument so that the method has the right this pointer to do its job as expected.
Calling apply with null as the first argument is like calling the function without providing any object for the this.
What does the apply method do?
The apply() method calls a function with a given this value and
arguments provided as an array (or an array-like object).
fun.apply(thisArg, [argsArray])
thisArg
The value of this provided for the call to fun. Note that this may not
be the actual value seen by the method: if the method is a function in
non-strict mode code, null and undefined will be replaced with the
global object, and primitive values will be boxed.
Further documentation can be found here.
One case where I have found this useful is when the function I'm calling is already bound to a particular context.
Because bound functions cannot be rebound, and they will always be called with the thisArg that was passed into bind, there is no use in passing a thisArg into call or apply. From source:
The bind() function creates a new bound function (BF).... When bound function is called, it calls internal method [[Call]] on [[BoundTargetFunction]], with following arguments Call(boundThis, args).
Here's an example:
class C {
constructor() {
this.a = 1;
}
}
function f(n, m) {
console.log(this.a + n + m);
}
let c = new C();
var boundF = f.bind(c, 2); // the context `c` is now bound to f
boundF.apply(null, [3]); // no reason to supply any context, since we know it's going to be `c`
I am bit late to answer this. I will try to give a long descriptive explanation here.
What is null in JavaScript?
The value null is a literal (not a property of the global object like undefined can be). It is one of JavaScript's primitive values.
In APIs, null is often retrieved in place where an object can be expected but no object is relevant.
fun.apply(thisArg, [argsArray])
thisArg: The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
argsArray: An array-like object, specifying the arguments with which fun should be called, or null or undefined if no arguments should be provided to the function. Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for browser compatibility information.
If you are using 'strict mode', then it is advisable to pass the this or
Math as the parameter.
Apply is useful when you want to pass along the responsibility for doing something to a function that is determined at run time, and pass a variable number of arguments to that function. You may or may not have any appropriate "this" context when you're doing that.
For example I use a library I wrote to facilitate listening for and raising application events that uses apply.
I wanted to be able to be able to raise an event like this:
EventManager.raise('some:event-name', arg1, arg2, arg3, ..);
..and have all of the registered handlers for that event get called with that list of arguments (arg1, arg2, etc). So in the raise function, it goes through the handlers that are registered for that event name and calls them, passing all the passed in arguments except for the event name, like this:
var args = [];
Array.prototype.push.apply(args, arguments);
args.shift();
for (var l in listeners) {
var listener = listeners[l];
listener.callback.apply(listener.context, args);
}
When a registered handler (listener.callback) is called, apply is used to pass along a variable number of arguments. Here I have allowed the listener to supply a this context for its event handler when the listener is defined, but that context might not be defined or it might be null, and that's perfectly fine.
For a long time the raise function didn't even facilitate using any callback context. I eventually came across a need for it, so I put in support for it, but most of the time I don't really need or use it.

How to inspect the javascript functions and its arguments

I'm very new to JS and I have been playing around with Jasmine.
In Jasmine, I can see a method called spyOn, which does inspect/spy the functions.
How does this works in js? Coming from Java background is it a proxy? How to write one?
You can find the precise implementation on GitHub, but here is a simplified explanation:
function mySpy(obj, methodName) {
// remember the original method
var originalMethod = obj[methodName];
// ... then replace it with a method that ...
obj[methodName] = function () {
// ... does whatever additional thing it wants to do ...
console.log(methodName + " called, first argument: " + arguments[0]);
// ... and then calls the original method with the same arguments,
// and returns the result.
return originalMethod.apply(this, arguments);
};
}
Now you can do this:
var o = {
inc: function (x) { return x + 1; }
};
mySpy(o, "inc");
console.log(o.inc(13));
This will output
inc called, first argument: 13
14
Three important things for you to know, coming from a Java background, are
In JavaScript, it is not a problem to change an object's methods after the fact, dynamically. Calling someObj.someMethod = someOtherFunction is perfectly valid. (To be 100% precise, you may not actually be overwriting the original method, because it may be somewhere up the prototype chain, instead of on the object itself. That's an advanced topic though, and not very important here. Also, Java's distinction beween methods and class members doesn't apply to JavaScript.)
The special "variable" arguments inside a function contains whatever arguments the function was called with. In Java terms, imagine that someMethod(Foo x1, Bar x2) always has an implicit second signature of the type someMethod(Object... arguments), meaning you could always use x1 and arguments[0] interchangeably.
obj.someName and obj["someName"] are entirely equivalent in JavaScript. Because of this, you can easily access/change an object's properties using the property name as a string, something that in Java you would have to use reflection for.

JavaScript Proxy Pattern Explained

I study JavaScript Proxy Pattern, but I still do not get, where I can benefit from it. I would therefore like to provide you with two examples and kindly ask you to point at the difference between them.
Please, take a look at the code below:
What is the difference between the two addEventListener calls? One of them calls handleDrop in regular way. The other uses Proxy Pattern.
What will I gain using Proxy pattern approach?
I tested both functions, and they both call handleDrop successfully.
DndUpload.prototype.buildDropZone = function ()
{
var self = this,
this.dropZone.addEventListener('drop', function (e) { self.handleDrop.call(self, e) }, false);
this.dropZone.addEventListener('drop', self.handleDrop, false);
DndUpload.prototype.handleDrop = function (e)
{
alert("test");
...
};
}
You can provide me with good reference which contains very clear explanation of Proxy Pattern in JavaScript.
So what you're describing in your example isn't so much a demonstration of the Proxy pattern as much as a demonstration of confusion regarding the "calling object" and how it works in JavaScript.
In JavaScript, functions are "first-class." This essentially means that functions are data just like any other data. So let's consider the following situation:
var fn = (function () { return this.x; }),
a = {
x : 1,
fn : fn,
},
x = 2,
nothing = (function (z) { return z; });
So, we have an object a, which has two properties: fn and x. We also have variables x, fn (which is a function returning this.x), and nothing (which returns whatever it gets passed).
If we evaluate a.x, we get 1. If we evaluate x, we get 2. Pretty simple, eh? Now, if we evaluate nothing(a.x), then we get 1. That's also very simple. But it's important to realize that the value 1 associated with the property a.x is not in any way connected to the object a. It exists independently and can be passed around simply as a value.
In JavaScript, functions work the same way. Functions that are properties (often called "methods") can be passed as simple references. However, in doing so, they can become disconnected from their object. This becomes important when you use the this keyword inside a function.
The this keyword references the "calling object." That's the object that is associated with a function when that function is evaluated. There are three basic ways to set the calling object for a function:
If the function is called using the dot operator (e.g. a.fn()), the relevant object (in the example, a) is set as the calling object.
If the function is called using the function's call or apply properties, then you can explicitly set the calling object (we'll see why this is useful in a second).
If no calling object is set through method 1 or method 2, the global object is used (in a browser, this is typically called window).
So, back to our code. If we call a.fn(), it will evaluate as 1. That's expected because the this keyword in the function will be set to a due to the use of the dot operator. However, if we call simply fn(), it will return 2 because it is referencing the x property of the global object (meaning our global x is used).
Now, here's where things get tricky. What if you called: nothing(a.fn)()? You might be surprised that the result is 2. This is because passing a.fn into nothing() passes a reference to fn, but does not retain the calling object!
This is the same concept as what's going on in your coding example. If your function handleDrop were to use the this keyword, you would find it has a different value depending on which handler form you use. This is because in your second example, you're passing a reference to handleDrop, but as with our nothing(a.fn)() example, by the time it gets called, the calling object reference is lost.
So let's add something else to the puzzle:
var b = {
x : 3
};
You'll note that while b has an x property (and therefore satisfies the requirements for fn's use of this), it doesn't have a property referencing fn. So if we wanted to call the fn function with its this set to b, it might seem we need to add a new property to b. But instead we can use the aforementioned apply method on fn to explicitly set b as the calling object:
fn.apply(b); //is 3
This can be used to "permanently" bind a calling object to a function by creating a new function "wrapper." It's not really permanently binding, it's just creating a new function that calls the old function with the desired calling object. Such a tool is often written like so:
Function.prototype.bind = function (obj) {
var self = this;
return function() {
return self.apply(obj, arguments);
};
};
So after executing that code, we could do the following:
nothing(a.fn.bind(a))(); //is 1.
It's nothing tricky. In fact, the bind() property is built into ES5 and works pretty much like the simple code above. And our bind code is actually a really complicated way to do something that we can do more simply. Since a has fn as a property, we can use the dot operator to call it directly. We can skip all the confusing use of call and apply. We just need to make sure when the function gets called, it gets called using the dot operator. We can see how to do it above, but in practice, it's far simpler and more intuitive:
nothing(function () { return a.fn(); })(); //is 1
Once you have an understanding of how data references can be stored in closure scope, how functions are first-class objects, and how the calling object works, this all becomes very simple to understand and reasonably intuitive.
As for "proxies," those also exploit the same concepts to hook into functions. So, let's say that you wanted to count the number of times a.fn gets called. You can do that by inserting a proxy, like so (making use of some concepts from our bind code from above):
var numCalls = (function () {
var calls = 0, target = a.fn;
a.fn = (function () {
calls++;
return target.apply(a, arguments);
});
return (function () {
return calls;
});
}());
So now, whenever you call numCalls(), it will return the number of times a.fn() was called without actually modifying the functionality of a.fn! which is pretty cool. However, you must keep in mind that you did change the function referenced by a.fn, so looking way back to the beginning of our code, you'll notice that a.fn is no longer the same as fn and can't be used interchangeably anymore. But the reasons should now be pretty obvious!
I know that was basically a week of JavaScript education in a couple pages of text, but that's about as simple as it gets. Once you understand the concepts, the functionality, usefulness, and power of many JavaScript patterns become very simple to understand.
Hope that made things clearer!
UPDATE: Thanks to #pimvdb for pointing out my unnecessary use of [].slice.call(arguments, 0). I have removed it because it's, well, unnecessary.
Basically, passing self.handleDrop directly is functionally equivalent to passing the following function:
function() {
return self.handleDrop.apply(this, arguments);
}
because everything is passed through to the original function:
The this value
The arguments
The return value
With this in mind, compare your functions as follows:
function(e) { self.handleDrop.call(self, e) }
function() { return self.handleDrop.apply(this, arguments); }
The difference with your proxy way is:
It doesn't pass the return value through.
It doesn't pass all arguments through (only the first, e)
It doesn't pass the this value through, but uses a predefined one: self.
Now, the first two items don't make a difference here, because addEventListener doesn't care about the return value, and it also only passes one argument anyway.
But the third item is important: it sets a different this value in the function. By default, this is the element you bind the event to (it it set by the browser). Using the proxy way, you can set another this value.
Now, in your snippet it is not fully clear why you're setting a prototype function each time buildDropZone is called. Usually you define prototype functions only once. But when your handler handleDrop is called using the proxy way, this refers to the DndUpload instance, which is consistent with prototype functions in general.
Consider the code below:
function printThis() {
console.log(this);
}
var someObject = {
performTest : function() {
var self = this;
someOtherObject.higherOrderFunction(printThis);
someOtherObject.higherOrderFunction(function(){printThis.call(self)});
}
}
var someOtherObject = {
higherOrderFunction : function(f) {
f();
}
}
What will someOtherObject.higherOrderFunction(printThis) return?
How about someOtherObject.higherOrderFunction(function(){printThis.call(self)})
The answer to the first question depends on who and how you call someObject.performTest(). If I just call someObject.performTest() from a global context, it will probably print Window.
The second one will always print the someObject instance no matter what.
The closures or 'proxy pattern' as you call it comes in handy when you want to control exactly the execution context of a function.
Note: this in javascript does not behave like it does in other languages(in Java for example).

Pass a function reference that has a variable as its name

I have the following javascript method:
function 123_test_function(){
}
The function is generated by java and sent to the client. The 123 is the id of the component so it could change. i.e I can have another function called 111_test_function()
I want to pass this function as a reference.
So I need to create the reference
var 123_test_function = function 123_test_function(){
}
In another js file inside an object I have a function that needs to use the 123_test_function reference like so:
useFunction(123_test_function);
The problem I'm having is which the 123 part of the function.
In this object I have a variable(uniqueID) which has the number at the beginning of the function.
I need the function call to be something like:
useFunction(uniqueID+"_test_function");
This doesn't seem to pass a function instead it passes a string.
Am I doing something wrong?
For one, identifiers (such as function names) cannot begin with a digit.
To solve your problem, use an object, like this:
// 1. define an object to hold all your functions
var allFunctions = {};
// 2. store any function with a unique string as the ID
allFunctions['123_test_function'] = function () {
// whatever
};
// 3. call the function
allFunctions['123_test_function']();
allFunctions[uniqueID + '_test_function']();
Objects are associative arrays. They store key/values pairs, so they do exactly what you want here.
Note that functions don't need a name in JavaScript, so I did not use on in step 2.
If the function is defined as global one, it will be a member of global object (window in case of browsers). Hence you can just do window['id_'+uniqueID+'_test_function'] to access your function
useFunction(window['id_'+uniqueID+'_test_function'])
(Identifiers cannot begin with numbers in JavaScript so I added the 'id_' prefix. You can of course change it to your liking.)
function test_function(number){
if(number == 1)
{
return function() {}
}
if(number == 2)
{
return function() {}
}
}
call the function like this
var func = test_function(1)
func();
As a couple of people have correctly pointed out, a function (or indeed variable) name cannot begin with a numeric. Also this syntax is wrong:
var 123_test_function = function 123_test_function(){
}
The correct syntax would be:
var 123_test_function = function() {
};
...although it should also be noted that the effect of this is exactly the same as a "traditional"
function 123_test_function() {
}
...declaration, in the context of the window object - since window is effectively the global scope of a JS environment in a browser, it doesn't matter how you define the functions, they will always be accessible from anywhere. Understanding exactly what each method of declaring a function means in Javascript is important - luckily, Douglas Crockford to the rescue once again...
People have suggested various methods for calling your named functions from the context of a string, which is basically attempting to use "variable variable" syntax, a subject that has been discussed on SO and elsewhere at length. The eval() approach should be avoided wherever possible - if you find yourself needing an eval() chances are you went wrong somewhere a while back. #Tomalak has the right idea with a collection of functions held in an object, but this still needs the slightly messy string approach to reference things that are actually being accessed by a numeric ID. The collection approach has the advantage of not cluttering up the window object with what are likely to be single/zero use members.
But the way I see it, all you actually need here is an indexed array of functions, where all you need is the numeric index in order to access them. I suggest you create your functions like this:
// Do this once at the top of your JS
var test_functions = [];
// Now, for each function you define:
test_functions[123] = function() {
// Do stuff here
};
// And when you need to call the functions:
var funcId = 123;
test_functions[funcId]();

Categories