Apply() Method's First Parameter Args - javascript

GAME = {};
GAME[1] = {
test: 1,
test2: 2
}
GAMELENGTH = (Math.max.apply(Math.max, Object.keys(GAME))) + 1;
GAMELENGTH2 = (Math.max.apply(Math.apply, Object.keys(GAME))) + 1;
GAMELENGTH3 = (Math.max.apply(null, Object.keys(GAME))) + 1;
console.log(GAMELENGTH);
console.log(GAMELENGTH2);
console.log(GAMELENGTH3);
JSFiddle: http://jsfiddle.net/agx85sba/2/
What exactly am I supposed to use as the first parameter for apply()? As all these different GAMELENGTH's have the same outcome but are taking in different parameters.

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.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
For your use-case it does not matter. The actual implementation of Math.max may not care about this.
You use apply to get the maximum of a list of values without the need to write them all to the function call (Math.max(1,2,3,4,5) vs var list = [1,2,3,4,5]; Math.max.apply(null, list)).

Related

Super simple javascript function call

Super simple function:
function equals(a,b){return a==b;}
When I call it like this it works fine and returns true:
equals(1,1)
When I call it like this though it returns false, and I don't understand why:
equals.call(1,1)
I thought invoking function.call was the same as simply invoking the function. What am I missing here?
The first argument that .call expects is a value for this within that function invocation followed by the arguments you want to pass to the function.
Since your function contains no reference to this, you can get the result you want by passing null as the first argument:
equals.call(null, 1,1);
You can find further details about this method at the MDN docs Function.prototype.call
The first argument in Function.prototype.call is for the value that the function will treat as this. Since the function doesn't use this, you can just pass in anything you like, such as null:
equals.call(null, 1, 1)
The first argument in when using .call is the reference for "this".
See this jsFiddle for an example: https://jsfiddle.net/4hfrc3sk/
The first argument for call should be this. Like this:
equals.call(this,1,1)
In your version it tried to compare one with undefined, because there was no third parameter provided.
Read more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
The first argument of .call is context (= what "this" will refer too).
So you can do:
equals.call(undefined, 1, 1);
But it is rather pointless.
More reading about .call: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
As it is stated here:
The call() method calls a function with a given this value and
arguments provided individually.
The first parameter is the value of this:
function.call(thisArg, arg1, arg2, ...)
Since you pass there the value of 1 this is used as the this, which apparently is not correct. You should pass at the start the null and the the two numbers.
equals.call(null, 1, 1)
If you want call to execute without specifying null or undefined as the first parameter, you could rewrite the code as follows:
function equals(a,b) {
var w = window;
return (w.a == w.b);
}
d = document;
d.g = d.getElementById;
var a = 1;
var b = 1;
var res = equals.call(a,b);
d.g("answer").innerHTML= "\n<BR>" + a + " == " + b + "? " + res + "\n";
a = 5;
b = 9;
res = equals.call(a,b);
d.g("answer").innerHTML += "\n<BR>" + a + " == " + b + "? " + res;
#answer {
font: 22pt Arial,Helvetica;
color: #090;
}
<div id="answer"></div>
See resource
However, if you want to simply provide a context of null or undefined in the function call, be sure that you leave out that argument in the function definition or an incorrect result may occur; see the good and the bad.

How to use apply with currying?

I have code that is using currying to get the average on an array that results from concatenating two arrays: an n size array and an m size array.
var avg = function(...n){
let tot=0;
for(let i=0; i<n.length; i++){
tot += n[i];
}
return tot/n.length;
};
var spiceUp = function(fn, ...n){
return function(...m){
return fn.apply(this, n.concat(m));
}
};
var doAvg = spiceUp(avg, 1,2,3);
console.log(doAvg(4,5,6));
In this line return fn.apply(this, n.concat(m));, I don't understand why do we need to use apply. What is the object we are binding with the average function and why does just normal calling (return fn(n.concat(m));) not work?
In that example, this is not that important. It would also work if instead of this you would pass an empty object instead. It's just an example on how to use apply.
What you need to focus is on the second parameter n.concat(m). They key concept here is that passing an array as a second argument you are calling that function (fn) passing each value in the array as an argument.
About your second question: no, it won't work because fn expects several arguments (one per value to calculate the average) while by doing return fn(n.concat(m)); you are just passing one argument, an array containing all values
Maybe you would understand it better with a simpler example:
function sum3params(a,b,c){
return a+b+c;
}
console.log(sum3params([3,4,2])) // won't work
console.log(sum3params.apply(this, [3,4,2])) // will work ('this' is not important here)
For this use case, it does not. But consider the following:
var foo = {
bar: 3
};
var addBar = function(a, b) { return a + b + this.bar };
foo.add3AndBar = spiceUp(addBar, 3);
foo.add3AndBar(1); // 7
Using apply means that your spiceUp function can be applied to methods as well as normal functions. For more likely example, consider partially applying when defining a method on a prototype:
const ENV = "linux";
DoesSomePlatformSpecificStuff.prototype.getPath = spiceUp(ENV);
apply also will spread the gathered array of arguments back out into positional arguments which can also be done like so:
return fn(...n.concat(m));
Which can be simplified as
return fn(...n, ...m);
Which is equivalent to
return fn.apply(undefined, n.concat(m));

Is there a JavaScript equivalent for C# 'params'?

I need a method that can have an arbitrary number of parameters. In C# we have the params statement. Do we have anything similar in JavaScript?
There is the arguments collection, which contains all arguments passed to the function.
There is a) no need to specify "optional" arguments in the function signature and b) any function accepts any number of parameters.
function foo() {
console.log(arguments);
}
foo(1,2,3,4); // logs [1, 2, 3, 4]
Likewise, there is no need to supply "required" arguments in a function call:
function foo(a, b, c, d) {
console.log(arguments);
}
foo(1,2); // logs [1, 2]
Any argument named in the signature but not supplied in the function call will be undefined.
Note that arguments behaves like an Array, but technically it isn't one. For example, you can call arguments[0], but you can't call arguments.slice(). What you can do to get around this is using the Array prototype:
Array.prototype.slice.call(arguments, 1, 2);
The so-called rest parameter ... is a new (ES6+) addition to the language and makes working with variadic functions more comfortable. #ArunCM's answer explains it.
I know this thread is too old but I believe something is missing here.
There is Rest parameter (introduced in ECMAScript 6) which will allow us to represent an indefinite number of arguments as an array.
It always returns an array. Which means even in defensive JavaScript land, it’s ok to do things like check .length of rest without guards.
Syntax :
function(a, b, ...theArgs) {
// ...
}
There are three main differences between rest parameters and the arguments object:
rest parameters are only the ones that haven't been given a separate name, while the arguments object contains all arguments passed to the function
the arguments object is not a real array, while rest parameters are Array instances, meaning methods like sort, map, forEach or pop can be applied on it directly;
the arguments object has additional functionality specific to itself (like the callee property).
Additional reading : Spread
function f(x, ...y) {
// y is an Array
return x * y.length;
}
console.log("Expected result : 3*2 = 6 & Actual result : " + f(3, "hello", true));
console.log("Expected result : 3*4 = 12 & Actual result : " + f(3, "a", true, "b", 1));
//here we are not passing anything to "y" but its still safe to check .length of "y" because it always return an array.
console.log("Expected result : 3*0 = 0 & Actual result : " + f(3));
Yes. arguments.
function concatStrings () {
var str = '';
for (var i = 0; i < arguments.length; i++) {
str += arguments[i];
}
return str;
}
Be aware that arguments isn't an array, so it doesn't have methods like join or push. It's just an array-like object (with numerical properties and a length property) so it can be iterated through.
JavaScript has arguments object inside functions. It contains of all params passed to the function.
More info
It is some sort of implicit in the special variable "arguments". Use like this:
function something(arg1, arg2) {
for (var i = 0; i < arguments.length; i++) {
var x = arguments[i];
}
}
Then you can call it like something(1, 2, 3, 'a', 'b', 'c')
More examples here: http://www.jtricks.com/javascript_tutorials/varargs.html
Javascript functions can accept any number of parameters by default. You can see them with the arguments variable.
See here.

What is the difference between call and apply?

What is the difference between using Function.prototype.apply() and Function.prototype.call() to invoke a function?
var func = function() {
alert('hello!');
};
func.apply(); vs func.call();
Are there performance differences between the two aforementioned methods? When is it best to use call over apply and vice versa?
The difference is that apply lets you invoke the function with arguments as an array; call requires the parameters be listed explicitly. A useful mnemonic is "A for array and C for comma."
See MDN's documentation on apply and call.
Pseudo syntax:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
There is also, as of ES6, the possibility to spread the array for use with the call function, you can see the compatibilities here.
Sample code:
function theFunction(name, profession) {
console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator
K. Scott Allen has a nice writeup on the matter.
Basically, they differ on how they handle function arguments.
The apply() method is identical to call(), except apply() requires an array as the second parameter. The array represents the arguments for the target method."
So:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
To answer the part about when to use each function, use apply if you don't know the number of arguments you will be passing, or if they are already in an array or array-like object (like the arguments object to forward your own arguments. Use call otherwise, since there's no need to wrap the arguments in an array.
f.call(thisObject, a, b, c); // Fixed number of arguments
f.apply(thisObject, arguments); // Forward this function's arguments
var args = [];
while (...) {
args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments
When I'm not passing any arguments (like your example), I prefer call since I'm calling the function. apply would imply you are applying the function to the (non-existent) arguments.
There shouldn't be any performance differences, except maybe if you use apply and wrap the arguments in an array (e.g. f.apply(thisObject, [a, b, c]) instead of f.call(thisObject, a, b, c)). I haven't tested it, so there could be differences, but it would be very browser specific. It's likely that call is faster if you don't already have the arguments in an array and apply is faster if you do.
Here's a good mnemonic. Apply uses Arrays and Always takes one or two Arguments. When you use Call you have to Count the number of arguments.
While this is an old topic, I just wanted to point out that .call is slightly faster than .apply. I can't tell you exactly why.
See jsPerf, http://jsperf.com/test-call-vs-apply/3
[UPDATE!]
Douglas Crockford mentions briefly the difference between the two, which may help explain the performance difference... http://youtu.be/ya4UHuXNygM?t=15m52s
Apply takes an array of arguments, while Call takes zero or more individual parameters! Ah hah!
.apply(this, [...])
.call(this, param1, param2, param3, param4...)
Follows an extract from Closure: The Definitive Guide by Michael Bolin. It might look a bit lengthy, but it's saturated with a lot of insight. From "Appendix B. Frequently Misunderstood JavaScript Concepts":
What this Refers to When a Function is Called
When calling a function of the form foo.bar.baz(), the object foo.bar is referred to as the receiver. When the function is called, it is the receiver that is used as the value for this:
var obj = {};
obj.value = 10;
/** #param {...number} additionalValues */
obj.addValues = function(additionalValues) {
for (var i = 0; i < arguments.length; i++) {
this.value += arguments[i];
}
return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);
If there is no explicit receiver when a function is called, then the global object becomes the receiver. As explained in "goog.global" on page 47, window is the global object when JavaScript is executed in a web browser. This leads to some surprising behavior:
var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN
Even though obj.addValues and f refer to the same function, they behave differently when called because the value of the receiver is different in each call. For this reason, when calling a function that refers to this, it is important to ensure that this will have the correct value when it is called. To be clear, if this were not referenced in the function body, then the behavior of f(20) and obj.addValues(20) would be the same.
Because functions are first-class objects in JavaScript, they can have their own methods. All functions have the methods call() and apply() which make it possible to redefine the receiver (i.e., the object that this refers to) when calling the function. The method signatures are as follows:
/**
* #param {*=} receiver to substitute for 'this'
* #param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* #param {*=} receiver to substitute for 'this'
* #param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;
Note that the only difference between call() and apply() is that call() receives the function parameters as individual arguments, whereas apply() receives them as a single array:
// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);
The following calls are equivalent, as f and obj.addValues refer to the same function:
obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);
However, since neither call() nor apply() uses the value of its own receiver to substitute for the receiver argument when it is unspecified, the following will not work:
// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);
The value of this can never be null or undefined when a function is called. When null or undefined is supplied as the receiver to call() or apply(), the global object is used as the value for receiver instead. Therefore, the previous code has the same undesirable side effect of adding a property named value to the global object.
It may be helpful to think of a function as having no knowledge of the variable to which it is assigned. This helps reinforce the idea that the value of this will be bound when the function is called rather than when it is defined.
End of extract.
It is useful at times for one object to borrow the function of another object, meaning that the borrowing object simply executes the lent function as if it were its own.
A small code example:
var friend = {
car: false,
lendCar: function ( canLend ){
this.car = canLend;
}
};
var me = {
car: false,
gotCar: function(){
return this.car === true;
}
};
console.log(me.gotCar()); // false
friend.lendCar.call(me, true);
console.log(me.gotCar()); // true
friend.lendCar.apply(me, [false]);
console.log(me.gotCar()); // false
These methods are very useful for giving objects temporary functionality.
Another example with Call, Apply and Bind.
The difference between Call and Apply is evident, but Bind works like this:
Bind returns an instance of a function that can be executed
First Parameter is 'this'
Second parameter is a Comma separated list of arguments (like Call)
}
function Person(name) {
this.name = name;
}
Person.prototype.getName = function(a,b) {
return this.name + " " + a + " " + b;
}
var reader = new Person('John Smith');
reader.getName = function() {
// Apply and Call executes the function and returns value
// Also notice the different ways of extracting 'getName' prototype
var baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);
console.log("Apply: " + baseName);
var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy");
console.log("Call: " + baseName);
// Bind returns function which can be invoked
var baseName = Person.prototype.getName.bind(this, "is a", "boy");
console.log("Bind: " + baseName());
}
reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/
I'd like to show an example, where the 'valueForThis' argument is used:
Array.prototype.push = function(element) {
/*
Native code*, that uses 'this'
this.put(element);
*/
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[4,5]);
array.push.call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
**details: http://es5.github.io/#x15.4.4.7*
Call() takes comma-separated arguments, ex:
.call(scope, arg1, arg2, arg3)
and apply() takes an array of arguments, ex:
.apply(scope, [arg1, arg2, arg3])
here are few more usage examples:
http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/
From the MDN docs on Function.prototype.apply() :
The apply() method calls a function with a given this value and
arguments provided as an array (or an array-like object).
Syntax
fun.apply(thisArg, [argsArray])
From the MDN docs on Function.prototype.call() :
The call() method calls a function with a given this value and arguments provided individually.
Syntax
fun.call(thisArg[, arg1[, arg2[, ...]]])
From Function.apply and Function.call in JavaScript :
The apply() method is identical to call(), except apply() requires an
array as the second parameter. The array represents the arguments for
the target method.
Code example :
var doSomething = function() {
var arr = [];
for(i in arguments) {
if(typeof this[arguments[i]] !== 'undefined') {
arr.push(this[arguments[i]]);
}
}
return arr;
}
var output = function(position, obj) {
document.body.innerHTML += '<h3>output ' + position + '</h3>' + JSON.stringify(obj) + '\n<br>\n<br><hr>';
}
output(1, doSomething(
'one',
'two',
'two',
'one'
));
output(2, doSomething.apply({one : 'Steven', two : 'Jane'}, [
'one',
'two',
'two',
'one'
]));
output(3, doSomething.call({one : 'Steven', two : 'Jane'},
'one',
'two',
'two',
'one'
));
See also this Fiddle.
Here's a small-ish post, I wrote on this:
http://sizeableidea.com/call-versus-apply-javascript/
var obj1 = { which : "obj1" },
obj2 = { which : "obj2" };
function execute(arg1, arg2){
console.log(this.which, arg1, arg2);
}
//using call
execute.call(obj1, "dan", "stanhope");
//output: obj1 dan stanhope
//using apply
execute.apply(obj2, ["dan", "stanhope"]);
//output: obj2 dan stanhope
//using old school
execute("dan", "stanhope");
//output: undefined "dan" "stanhope"
Fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.
The difference is that call() takes the function arguments separately, and apply() takes the function arguments in an array.
Summary:
Both call() and apply() are methods which are located on Function.prototype. Therefore they are available on every function object via the prototype chain. Both call() and apply() can execute a function with a specified value of the this.
The main difference between call() and apply() is the way you have to pass in arguments into it. In both call() and apply() you pass as a first argument the object you want to be the value as this. The other arguments differ in the following way:
With call() you have to put in the arguments normally (starting from the second argument)
With apply() you have to pass in array of arguments.
Example:
let obj = {
val1: 5,
val2: 10
}
const summation = function (val3, val4) {
return this.val1 + this.val2 + val3 + val4;
}
console.log(summation.apply(obj, [2 ,3]));
// first we assign we value of this in the first arg
// with apply we have to pass in an array
console.log(summation.call(obj, 2, 3));
// with call we can pass in each arg individually
Why would I need to use these functions?
The this value can be tricky sometimes in javascript. The value of this determined when a function is executed not when a function is defined. If our function is dependend on a right this binding we can use call() and apply() to enforce this behaviour. For example:
var name = 'unwantedGlobalName';
const obj = {
name: 'Willem',
sayName () { console.log(this.name);}
}
let copiedMethod = obj.sayName;
// we store the function in the copiedmethod variable
copiedMethod();
// this is now window, unwantedGlobalName gets logged
copiedMethod.call(obj);
// we enforce this to be obj, Willem gets logged
We can differentiate call and apply methods as below
CALL : A function with argument provide individually.
If you know the arguments to be passed or there are no argument to pass you can use call.
APPLY : Call a function with argument provided as an array. You can use apply if you don't know how many argument are going to pass to the function.
There is a advantage of using apply over call, we don't need to change the number of argument only we can change a array that is passed.
There is not big difference in performance. But we can say call is bit faster as compare to apply because an array need to evaluate in apply method.
The main difference is, using call, we can change the scope and pass arguments as normal, but apply lets you call it using arguments as an Array (pass them as an array). But in terms of what they to do in your code, they are pretty similar.
While the syntax of this function is almost identical to that of
apply(), the fundamental difference is that call() accepts an argument
list, while apply() accepts a single array of arguments.
So as you see, there is not a big difference, but still, there are cases we prefer using call() or apply(). For example, look at the code below, which finding the smallest and largest number in an array from MDN, using the apply method:
// min/max number in an array
var numbers = [5, 6, 2, 3, 7];
// using Math.min/Math.max apply
var max = Math.max.apply(null, numbers);
// This about equal to Math.max(numbers[0], ...)
// or Math.max(5, 6, ...)
var min = Math.min.apply(null, numbers)
So the main difference is just the way we passing the arguments:
Call:
function.call(thisArg, arg1, arg2, ...);
Apply:
function.apply(thisArg, [argsArray]);
Difference between these to methods are, how you want to pass the parameters.
“A for array and C for comma” is a handy mnemonic.
Call and apply both are used to force the this value when a function is executed. The only difference is that call takes n+1 arguments where 1 is this and 'n' arguments. apply takes only two arguments, one is this the other is argument array.
The advantage I see in apply over call is that we can easily delegate a function call to other function without much effort;
function sayHello() {
console.log(this, arguments);
}
function hello() {
sayHello.apply(this, arguments);
}
var obj = {name: 'my name'}
hello.call(obj, 'some', 'arguments');
Observe how easily we delegated hello to sayHello using apply, but with call this is very difficult to achieve.
Even though call and apply achive the same thing, I think there is atleast one place where you cannot use call but can only use apply. That is when you want to support inheritance and want to call the constructor.
Here is a function allows you to create classes which also supports creating classes by extending other classes.
function makeClass( properties ) {
var ctor = properties['constructor'] || function(){}
var Super = properties['extends'];
var Class = function () {
// Here 'call' cannot work, only 'apply' can!!!
if(Super)
Super.apply(this,arguments);
ctor.apply(this,arguments);
}
if(Super){
Class.prototype = Object.create( Super.prototype );
Class.prototype.constructor = Class;
}
Object.keys(properties).forEach( function(prop) {
if(prop!=='constructor' && prop!=='extends')
Class.prototype[prop] = properties[prop];
});
return Class;
}
//Usage
var Car = makeClass({
constructor: function(name){
this.name=name;
},
yourName: function() {
return this.name;
}
});
//We have a Car class now
var carInstance=new Car('Fiat');
carInstance.youName();// ReturnsFiat
var SuperCar = makeClass({
constructor: function(ignore,power){
this.power=power;
},
extends:Car,
yourPower: function() {
return this.power;
}
});
//We have a SuperCar class now, which is subclass of Car
var superCar=new SuperCar('BMW xy',2.6);
superCar.yourName();//Returns BMW xy
superCar.yourPower();// Returns 2.6
Let me add a little detail to this.
these two calls are almost equivalent:
func.call(context, ...args); // pass an array as list with spread operator
func.apply(context, args); // is same as using apply
There’s only a minor difference:
The spread operator ... allows passing iterable args as the list to call.
The apply accepts only array-like args.
So, these calls complement each other. Where we expect an iterable, call works, where we expect an array-like, apply works.
And for objects that are both iterable and array-like, like a real array, we technically could use any of them, but apply will probably be faster because most JavaScript engines internally optimize it better.
I just want to add a simple example to a well explained post by flatline, which makes it easy to understand for beginners.
func.call(context, args1, args2 ); // pass arguments as "," separated value
func.apply(context, [args1, args2]); // pass arguments as "Array"
we also use "Call" and "Apply" method for changing reference as defined in code below
let Emp1 = {
name: 'X',
getEmpDetail: function(age, department) {
console.log(`Name: ${this.name} Age: ${age} Department: ${department}`)
}
}
Emp1.getEmpDetail(23, 'Delivery')
// 1st approach of changing "this"
let Emp2 = {
name: 'Y',
getEmpDetail: Emp1.getEmpDetail
}
Emp2.getEmpDetail(55, 'Finance')
// 2nd approach of changing "this" using "Call" and "Apply"
let Emp3 = {
name: 'Emp3_Object',
}
Emp1.getEmpDetail.call(Emp3, 30, 'Admin')
// here we have change the ref from **Emp1 to Emp3** object
// now this will print "Name = Emp3_Object" because it is pointing to Emp3 object
Emp1.getEmpDetail.apply(Emp3, [30, 'Admin'])
The call() method calls a function with a given this value and a second parameter which are arguments separated by comma.
object.someMethod.call( someObject, arguments )
The apply() method is the same as call except the fact that the second argument it takes is an array of arguments .
object.someMethod.apply( someObject, arrayOfarguments )
var car = {
name: "Reno",
country: "France",
showBuyer: function(firstName, lastName) {
console.log(`${firstName} ${lastName} just bought a ${this.name} from ${this.country}`);
}
}
const firstName = "Bryan";
const lastName = "Smith";
car.showBuyer(firstName, lastName); // Bryan just bought a Reno from France
const obj = { name: "Maserati", country: "Italy" };
car.showBuyer.call(obj, firstName, lastName); // Bryan Smith just bought a Maserati from Italy
car.showBuyer.apply(obj, [firstName, lastName]); // Bryan Smith just bought a Maserati from Italy

What is this javascript code doing?

this.String = {
Get : function (val) {
return function() {
return val;
}
}
};
What is the ':' doing?
this.String = {} specifies an object. Get is a property of that object. In javascript, object properties and their values are separated by a colon ':'.
So, per the example, you would call the function like this
this.String.Get('some string');
More examples:
var foo = {
bar : 'foobar',
other : {
a : 'wowza'
}
}
alert(foo.bar); //alerts 'foobar'
alert(foo.other.a) //alerts 'wowza'
Others have already explained what this code does. It creates an object (called this.String) that contains a single function (called Get). I'd like to explain when you could use this function.
This function can be useful in cases where you need a higher order function (that is a function that expects another function as its argument).
Say you have a function that does something to each element of an Array, lets call it map. You could use this function like so:
function inc (x)
{
return x + 1;
}
var arr = [1, 2, 3];
var newArr = arr.map(inc);
What the map function will do, is create a new array containing the values [2, 3, 4]. It will do this by calling the function inc with each element of the array.
Now, if you use this method a lot, you might continuously be calling map with all sorts of arguments:
arr.map(inc); // to increase each element
arr.map(even); // to create a list of booleans (even or odd)
arr.map(toString); // to create a list of strings
If for some reason you'd want to replace the entire array with the same string (but keeping the array of the same size), you could call it like so:
arr.map(this.String.Get("my String"));
This will create a new array of the same size as arr, but just containing the string "my String" over and over again.
Note that in some languages, this function is predefined and called const or constant (since it will always return the same value, each time you call it, no matter what its arguments are).
Now, if you think that this example isn't very useful, I would agree with you. But there are cases, when programming with higher order functions, when this technique is used.
For example, it can be useful if you have a tree you want to 'clear' of its values but keep the structure of the tree. You could do tree.map(this.String.Get("default value")) and get a whole new tree is created that has the exact same shape as the original, but none of its values.
It assigns an object that has a property "Get" to this.String. "Get" is assigned an anonymous function, which will return a function that just returns the argument that was given to the first returning function. Sounds strange, but here is how it can be used:
var ten = this.String["Get"](10)();
ten will then contain a 10. Instead, you could have written the equivalent
var ten = this.String.Get(10)();
// saving the returned function can have more use:
var generatingFunction = this.String.Get("something");
alert(generatingFunction()); // displays "something"
That is, : just assigns some value to a property.
This answer may be a bit superflous since Tom's is a good answer but just to boil it down and be complete:-
this.String = {};
Adds an object to the current object with the property name of String.
var fn = function(val) {
return function() { return(val); }
}
Returns a function from a closure which in turn returns the parameter used in creating the closure. Hence:-
var fnInner = fn("Hello World!");
alert(fnInner()); // Displays Hello World!
In combination then:-
this.String = { Get: function(val) {
return function() { return(val); }
}
Adds an object to the current object with the property name of String that has a method called Get that returns a function from a closure which in turn returns the parameter used in creating the closure.
var fnInner = this.String.Get("Yasso!");
alert(fnInner()); //displays Yasso!

Categories

Resources