Curried JavaScript - calling - javascript

I am admittedly a beginner with JavaScript, but I need to piece together someone else's code and I am having trouble understanding the following function and how to call it in node.
const invoke = method => object => object[method]
This obviously is a function that takes a method that returns another function that takes an object that then returns object[method], but what exactly is the purpose? How would one use this? Thank you.

the way i see it is as the const states, it invokes a function stored in an object ,
as you mentionned, this can be broken down to :
const invoke = (method) => {
return (object) => {
return object[method] ;
}
}
the goal of this i believe is that you can call it ( like you're telling a story ) expressively and concisely : invoke the function a from the functions object. ( functionnal-programming )
from this article about functional programming
Functional programming is declarative rather than imperative, and
application state flows through pure functions. Contrast with object
oriented programming, where application state is usually shared and
colocated with methods in objects.
but the term invoke got me thinking about Immediately invoked functions, so the usage of the const invoke can be :
getting function from the object ( without executing it ) not to have to instantiate the whole object and having the function in a variable and maybe manipulate it's prototype.
calling the function ( with parenthesis ).
getting a property from an object.
immediately invoke a function in an object.
const myFns = {
'a' : function(x){
console.log(x || 'something to log when no params passed');
},
'b': {
username : 'Doe'
}
}
const invoke = method => object => object[method]
let myFunction = invoke('a')(myFns);
myFunction('hello from myFunction'); // call it or modify myFunction.prototype ... etc.
invoke('a')(myFns)('hello'); // simply call it
let user = invoke('b')(myFns); // get a property
console.log(user.username);
(invoke('a')(myFns))(); // immidiatly invoke the function
probalby to avoid eval() :P

The name 'invoke' suggests it should really be written like this:
const invoke = method => object => object[method]()
The () is the invocation. It's very general, so hard to say exactly how it would be used, but here's a silly example.
class Dog {
speak () { console.log('woof') }
}
var dogs = [ new Dog(), new Dog(), new Dog() ];
dogs.forEach( invoke( 'speak' ) );
-> 'woof'
-> 'woof'
-> 'woof'
It's a pretty common pattern to let an array method like forEach do the second call of a higher-order function like this.

Related

Calling Objects as Functions JavaScript

In JavaScript, functions are objects, except that they can be called and executed, this is comparable to overloading the () operator of an object in other languages.
Can I apply this functionality to any object?
I know there isn't a property like [Symbol.call] or something comparable. If there is something comparable, I would greatly appreciate it if you could inform me of what it is.
If declaring objects and assigning properties to them is my only option that's okay, but I'd prefer if this could be done using a class, like C++ for example.
I could do something like this
function func(...) {
...
}
func.foo = x,
func.bar = y;
but it would be more preferable if I could do something more like
const func = {
[`()`]: function(...) {
...
},
foo: x,
bar: y
};
Can I apply this functionality to any object?“
No. As of ECMAScript 10th Edition (2019) this is not possible.
The ()-operator/expression construct can only be used on function objects.
This is because it uses the [[Call]] internal method. Section 7.3.12 Call indicates this is only defined for function objects and the specification makes no provision to add the [[Call]] internal method to other objects.
7.3.12 Call ( F, V [ , argumentsList ] )
The abstract operation Call is used to call the [[Call]] internal method of a function object. [..]
The specification is written in such a way that a future revision might add generalized support.
Anyway, as shown in the question, function objects can be mutated as a proxy: so carry on, flavoring as desired.
So it might help to give a more concrete example of what you want, but here's a few options that can pretty much replicate, and more, the things you have mentioned.
This is like your first example. I'm guessing this isn't what you actually want. Notice foo and bar are static.
const func = Object.assign( function(in){ console.log(in, func.foo, func.bar) }, { foo: x, bar: y } );
This one is probably closer to what you'd see in a class with () overloaded
const func = ( function(in){ console.log(in, this.foo, this.bar) } ).bind({ foo: x, bar: y });
Or something like this:
o = o => o['()'].bind(o)
const func = o({
"()": function(x){ console.log(x, this.foo, this.bar) },
foo: 1,
bar: 2
});
Takes the property value of '()', and binds this to the object. You also use Object.assign to copy the properties on to the function.
Other way of expression
const func = (x,y) => ({
foo: x, bar: y,
plusone: () => func(x+1,y+1)
showfoo() { return this.foo }
})
You could do stuff like this, for example from within an outer IIFE function, returning different types of object formatted data. The IIFE can be passed as a parameter to another function in a modular script file, where controller's return data can be reached with dot notation controllerAsParameter.dostuff or controllerAsParameter.getNumbers.percentage.
Is my interpretation correct, based on your last example, that you're after something like this?
const controller = (function() {
return {
doStuff: function() {
data.everything.forEach(function(foo) {
foo.calculateStuff(data.totals.bar);
});
},
getNumbers: function() {
return {
abc: data.abc,
totalDef: data.totals.def,
totalGhi: data.totals.ghi,
percentage: data.percentage
}
}
}
})();

Javascript function inside functions

Today I observed the following syntax (simplified example):
const test = fn => () => console.log(fn)
test('foo')();
Having a hard time wrapping my head around this but it still remains vague to me. What exactly happens step by step?
Let's rewrite this in a way which maybe more understandable for you
const test = function(fn){
return function (){
console.log(fn);
}
}
test('foo')();
Do you understand it now? If yes this is same as your example just uses normal function instead of arrow functions.
You also need to know what a closure is to understand this.
As the answers already mentioned you are creating a closure.
In my answer, I want to say what it is a closure good for:
Imagin you want to greet three persons and two of them are your frinds and one is your boss. You want to greet your frinds with "Hi" but your boss with "Hello".
const greet = greetingWord => name =>
`${greetingWord}, ${name}`
const greetFrind = greet('Hi')
const greetBoss = greet('Hello')
We create a function greet which takes one arguement an will return a new function with one argument too (greet = greetingWord => name). Once we implement it we can define a greeter for our frinds and for the boss.
const greet = greetingWord => name =>
`${greetingWord}, ${name}`
const greetFrind = greet('Hi')
const greetBoss = greet('Hello')
console.log(greetFrind('Paul'))
console.log(greetFrind('Julia'))
console.log(greetBoss('Mr. Paker'))
So this is basic concept of closure in JavaScript. If you rewrite the code in ES5:
var test = function(fn){
return function(){
console.log(fn);
};
}
test('foo')();
So the inner function has access to the argument that was passed into the outer function. So that's why you are getting "foo"

Why pass an undefined javascript function parameter?

So I'm learning Javascript and I see this code:
var apple = {//... an object with some properties};
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});
Where someMethod and a_property_of_apple are valid methods and properties.
My question pertains to the argument, b, of the anonymous function which is not declared or defined anywhere else:
function (b) {return ...
What is going on here? What is b and why is it being used?
Apologies in advance for the basic nature of the question. If someone just wants to drop some focused terms on me to read up on that would be great short of an explanation.
The anonymous function is a callback function being passed to the apple.method() invocation.
apple.method() will invoke that anonymous function at some point during it's execution, ( or pass it to another function ). Whenever it's invoked it will be invoked with an argument that will be available inside the callback. You could call it b, or response, or whatever you want (logical names are best) and be able to use it within the anonymous function.
You should read about Callback functions over at MDN.
EDIT: I will explain the parts to you
var apple = {} This is the definition of an object
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple}); is defining that fruit is equal to the return value of the invocation of apple.someMethod(...)
apple.someMethod(function (b) {return b.a_property_of_apple}); is the invocation of apple.someMethod with function (b) {return b.a_property_of_apple} as the only argument.
The b argument in the anonymous function function (b) {return b.a_property_of_apple} will be passed to it's invocation within the apple.someMethod.
Here is an example snippet.
// define apple
var apple = {
// define method
someMethod: function( callback ) {
var obj = {
a_property_of_apple: "Eat me!" // this will be returned
}
// return the invocation of callback with obj as argument
return callback(obj);
}
}
var fruit = apple.someMethod(function (b) {return b.a_property_of_apple});
console.log(fruit);
EDIT: Ok, going to use something slightly less abstract as an example.
// notice employees being passed to this function
// that is called an argument and is usable inside the function
var orginization = function( employees ) {
// this will take the empoyees argument and assign it to this.employees
// or set this.employees to an empty array if there is no employees argument
this.employees = employees || [ ];
// this is a method ( a method is a function on an object )
// this function takes 3 arguments
this.addEmployee = function( employee ) {
// we use the 3 arguments to push a new object with title, name, and salary
// properties provided by the function arguments
this.employees.push( employee );
}
// this method returns the value stored in this.employees
this.getEmployees = function() {
return this.employees;
}
}
// this is a variable an array of employees only containing 1 employee
// i will use it in the creation of my new orginization
var employess = [
{
title: "CEO",
name: "Enola",
salary: "$$$$$$$"
}
];
// i use the new to create learningInc from originization( employees )
// originization is a constructor function which creates an object
// with methods and properties found on the constructor
var learningInc = new orginization( employess );
// console.log learningInc.getEmployees() an you will see still only the CEO
// works here
console.log( "before newHire: ", learningInc.getEmployees() );
// lets make a newHire
var newHire = {
title: "Peon",
name: "Sadly McFrownFace",
salary: "$"
};
// add the newHire to the employess of learningInc wth out getEmployees() method
learningInc.addEmployee( newHire );
// log the new value of learningInc.getEmployees and you see we now have 2 employees
console.log( "after newHire: ", learningInc.getEmployees() );
Ok now notice this line var learningInc = new orginization( employess );
The employees variable I'm passing to this function as an argument is used in this function var orginization = function( employees ) { ... }.
Hope this help.
My question pertains to the parameter, b, of the anonymous function which is not declared or defined anywhere else: What is going on here?
What is b and why is it being used?
Why you say it is not declared? It is declared right there. Consider this simple JavaScript function:
function doSomething(a, b){
//do something here;
}
In this code, we are creating a function, naming it "doSomething", and declaring two parameters for it a and b. This is how we declare function parameters in JavaScript. Now your example:
function (b) {return ...
is exactly the same, except we didn't give this function a name, which means it is an anonymous function. That's the only difference, but its parameter b is declared right there like any standard function. So there is nothing special going here, it's a standard function parameter and used as such.
There are a couple concepts at work here
Function declarations vs function expressions; you can use function as an operator to define a function, and assign the function to an identifier and pass it around like any normal object
Callbacks; you can pass a function CB into another function A to be called by A (as defined by A)
Passing something without an identifier
Function Declaration
// declare function
function foo(argFoo) {
console.log('foo', argFoo);
}
// invoke function
foo('was declared'); // "foo" "was declared"
Function Expression
// express function
var bar = function (argBar) {
console.log('bar', argBar);
};
// invoke function
bar('was expressed'); // "bar" "was expressed"
Callbacks
function fizz(callback) {
console.log('first I fizz');
callback();
}
function buzz() {
console.log('then I buzz');
}
fizz(buzz);
// "first I fizz"
// "then I buzz"
Passing without an Identifier,
Basically, defining things in-place
// say we have some fn fizzbuzz
function fizzbuzz(foo) {
console.log(foo);
}
// we could pre-define what we want to pass to it
var i = 1;
fizzbuzz(i); // 1
// or we could pass directly
fizzbuzz(1); // 1
// with anything we like
fizzbuzz({some: 'object'}); // {some: "object"}
// even a function
fizzbuzz(function () {}); // function () {}
Maybe if I break down what is happening into more readable code, you can see what is happening.
someMethod is a method that take a function as an argument. This is more easily seen when broken down like below.
It's up to someMethod to determine what they do with that function. In this example, I am executing the function being passed into someMethod and passing it my this context.
var apple = {
name: 'Apple',
someMethod: function(func) {
return func(this);
}
};
function getName (b) {
return b.name;
};
const name = apple.someMethod(getName); // Apple
To your question: b is defined as the first argument to your anonymous function. This is more clearly expressed when the code is broken out above. But you could also express it like this:
const name = apple.someMethod(function(x) { return x.name; }); // Apple
or like this using ES6:
const name = apple.someMethod(x => x.name); // Apple

How can I reference a `this` property within a method of `this`?

I append a services property to this:
function Client(){
this.services = {
'propertyName' : {}
};
and then append a method to this, in which I need to reference the services property of the instance of client:
function Client(){
this.services = {
'propertyName' : {}
};
this.someMethod = function () {
if (this.services['propertyName']) {
//do something
}
}
}
var clientName = new Client();
But this.services - line 6 is undefined. How can I use a property assigned to this in a method assigned to this? It seems like it should be possible because by the time that method is called by the constructor, the services property will exist for the object. Is this a language limitation? Is it possible? Should it be?
But this.services - line 6 is undefined.
That will depend entirely on how you call someMethod. If you call it like this:
clientName.someMethod();
...it'll be fine, because this within the call will be the object created by new Client that you've put the services property on. But in JavaScript, this is not a fixed thing with normal functions, it's set by how you call the function. So:
var f = clientName.someMethod;
f();
...would fail, because this wouldn't be the object you expect. (This isn't true of ES6's new "arrow" functions, which get this from where they're defined, not how they're called.)
You mostly see this when functions are used as callbacks:
doSomething(clientName.someMethod);
...because doSomething doesn't know what object to use as this.
You can fix it by using Function#bind:
doSomething(clientName.someMethod.bind(clientName));
or similarly:
var f = clientName.someMethod.bind(clientName);
f();
Function#bind creates a new function that, when called, will call the original with this set to the argument you give it.
Just to flesh out my ES6 comment above: In ES6, if you had:
function Client(){
this.services = {
'propertyName' : {}
};
this.someMethod = () => { // <== ES6 "arrow" function
if (this.services['propertyName']) {
//do something
}
}
}
...it wouldn't matter how you called someMethod, this would be what it is where that function was created. V. handy. :-)

Method vs Functions, and other questions

With respect to JS, what's the difference between the two? I know methods are associated with objects, but am confused what's the purpose of functions? How does the syntax of each of them differ?
Also, what's the difference between these 2 syntax'es:
var myFirstFunc = function(param) {
//Do something
};
and
function myFirstFunc(param) {
//Do something
};
Also, I saw somewhere that we need to do something like this before using a function:
obj.myFirstFunc = myFirstFunc;
obj.myFirstFunc("param");
Why is the first line required, and what does it do?
Sorry if these are basic questions, but I'm starting with JS and am confused.
EDIT: For the last bit of code, this is what I'm talking about:
// here we define our method using "this", before we even introduce bob
var setAge = function (newAge) {
this.age = newAge;
};
// now we make bob
var bob = new Object();
bob.age = 30;
// and down here we just use the method we already made
bob.setAge = setAge;
To answer your title question as to what is the difference between a 'function' and a 'method'.
It's semantics and has to do with what you are trying to express.
In JavaScript every function is an object. An object is a collection of key:value pairs. If a value is a primitive (number, string, boolean), or another object, the value is considered a property. If a value is a function, it is called a 'method'.
Within the scope of an object, a function is referred to as a method of that object. It is invoked from the object namespace MyObj.theMethod(). Since we said that a function is an object, a function within a function can be considered a method of that function.
You could say things like “I am going to use the save method of my object.” And "This save method accepts a function as a parameter.” But you generally wouldn't say that a function accepts a method as a parameter.
Btw, the book JavaScript Patterns by Stoyan Stefanov covers your questions in detail, and I highly recommend it if you really want to understand the language. Here's a quote from the book on this subject:
So it could happen that a function A, being an object, has properties and methods, one of which happens to be another function B. Then B can accept a function C as an argument and, when executed, can return another function D.
There is a slight difference -
Method : Method is a function when object is associated with it.
var obj = {
name : "John snow",
work : function someFun(paramA, paramB) {
// some code..
}
Function : When no object is associated with it , it comes to function.
function fun(param1, param2){
// some code...
}
Many answers are saying something along the lines that a method is what a function is called when it is defined on an object.
While this is often true in the way the word is used when people talk about JavaScript or object oriented programming in general (see here), it is worth noting that in ES6 the term method has taken on a very specific meaning (see section 14.3 Method Definitions of the specs).
Method Definitions
A method (in the strict sense) is a function that was defined through the concise method syntax in an object literal or as a class method in a class declaration / expression:
// In object literals:
const obj = {
method() {}
};
// In class declarations:
class MyClass {
method() {}
}
Method Specificities
This answer gives a good overview about the specificities of methods (in the strict sense), namely:
methods get assigned an internal [[HomeObject]] property which allows them to use super.
methods are not created with a prototype property and they don't have an internal [[Construct]] method which means that they cannot be called with new.
the name of a method does not become a binding in the method's scope.
Below are some examples illustrating how methods (in the strict sense) differ from functions defined on objects through function expressions:
Example 1
const obj = {
method() {
super.test; // All good!
},
ordinaryFunction: function ordinaryFunction() {
super.test; // SyntaxError: 'super' keyword unexpected here
}
};
Example 2
const obj = {
method() {},
ordinaryFunction: function ordinaryFunction() {}
};
console.log( obj.ordinaryFunction.hasOwnProperty( 'prototype' ) ); // true
console.log( obj.method.hasOwnProperty( 'prototype' ) ); // false
new obj.ordinaryFunction(); // All good !
new obj.method(); // TypeError: obj.method is not a constructor
Example 3
const obj = {
method() {
console.log( method );
},
ordinaryFunction: function ordinaryFunction() {
console.log( ordinaryFunction );
}
};
obj.ordinaryFunction() // All good!
obj.method() // ReferenceError: method is not defined
A method is a property of an object whose value is a function. Methods are called on objects in the following format: object.method().
//this is an object named developer
const developer = {
name: 'Andrew',
sayHello: function () {
console.log('Hi there!');
},
favoriteLanguage: function (language) {
console.log(`My favorite programming language is ${language}`);
}
};
// favoriteLanguage: and sayHello: and name: all of them are proprieties in the object named developer
now lets say you needed to call favoriteLanguage propriety witch is a function inside the object..
you call it this way
developer.favoriteLanguage('JavaScript');
// My favorite programming language is JavaScript'
so what we name this: developer.favoriteLanguage('JavaScript');
its not a function its not an object? what it is? its a method
Your first line, is creating an object that references a function. You would reference it like this:
myFirstFunc(param);
But you can pass it to another function since it will return the function like so:
function mySecondFunction(func_param){}
mySecondFunction(myFirstFunc);
The second line just creates a function called myFirstFunc which would be referenced like this:
myFirstFunc(param);
And is limited in scope depending on where it is declared, if it is declared outside of any other function it belongs to the global scope. However you can declare a function inside another function. The scope of that function is then limited to the function its declared inside of.
function functionOne(){
function functionTwo(){}; //only accessed via the functionOne scope!
}
Your final examples are creating instances of functions that are then referenced though an object parameter. So this:
function myFirstFunc(param){};
obj.myFirst = myFirstFunc(); //not right!
obj.myFirst = new myFirstFunc(); //right!
obj.myFirst('something here'); //now calling the function
Says that you have an object that references an instance of a function. The key here is that if the function changes the reference you stored in obj.myFirst will not be changed.
While #kevin is basically right there is only functions in JS you can create functions that are much more like methods then functions, take this for example:
function player(){
this.stats = {
health: 0,
mana: 0,
get : function(){
return this;
},
set : function( stats ){
this.health = stats.health;
this.mana = stats.mana;
}
}
You could then call player.stats.get() and it would return to you the value of heath, and mana. So I would consider get and set in this instance to be methods of the player.stats object.
A function executes a list of statements example:
function add() {
var a = 2;
var b = 3;
var c = a + b;
return c;
}
1) A method is a function that is applied to an object example:
var message = "Hello world!";
var x = message.toUpperCase(); // .toUpperCase() is a built in function
2) Creating a method using an object constructor. Once the method belongs to the object you can apply it to that object. example:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.name = function() {return this.firstName + " " + this.lastName;};
}
document.getElementById("demo").innerHTML = person.fullName(); // using the
method
Definition of a method: A method is a property of an object that is a function. Methods are defined the way normal functions are defined, except that they have to be assigned as the property of an object.
var myFirstFunc = function(param) {
//Do something
};
and
function myFirstFunc(param) {
//Do something
};
are (almost) identical. The second is (usually) just shorthand. However, as this jsfiddle (http://jsfiddle.net/cu2Sy/) shows, function myFirstFunc will cause the function to be defined as soon as the enclosing scope is entered, whereas myFirstFunc = function will only create it once execution reaches that line.
As for methods, they have a this argument, which is the current object, so:
var obj = {};
obj.func = function( ) {
// here, "this" is obj
this.test = 2;
}
console.log( obj.test ); // undefined
obj.func( );
console.log( obj.test ); // 2
The exact syntax you showed is because you can also do this:
function abc( ) {
this.test = 2;
}
var obj = {};
obj.func = abc;
obj.func( ); // sets obj.test to 2
but you shouldn't without good reason.
ecma document
4.3.31method :
function that is the value of a property
NOTE When a function is called as a method of an object, the object is
passed to the function as its this value.
It is very clear: when you call a function if it implicitly has a this (to point an object) and if you can't call the function without an object, the function deserves to name as method.

Categories