How to find if variable call or function call? - javascript

Note: This question is based on firestore admin SDK, but it is a general JS question.
Working with JS firestore admin SDK, this puzzled me a lot. Compare these 2 examples
Request a database value
admin.firestore().collection('my-Col').doc('my-doc').get().then(...)
Get a server timestamp is
admin.firestore.FieldValue.serverTimestamp()
In 1st example, it is admin.firestore() , in 2nd example it is admin.firestore
How it is possible to have a first behavior if called as function, another behavior if called as object key?
Maybe admin.firestore() calls a constructor... But then, how to get static value (whatever constructor called before or not) by doing admin.firestore?

From #jonrsharpe:
"A JavaScript function can also have arbitrary properties"
You gave me the tip! Built a small example to test
const bill = () => ({
friend: "boule"
});
bill.name = "bill";
const base = {
bill: bill
};
console.log(base.bill().friend);
// -> boule
console.log(base.bill.name);
// -> bill
This is what I was looking for. Thanks a lot.

In Javascript, functions can also have properties on their own. In javascript, you have either primitive values (boolean, numbers, strings, null and undefined) or (all the rest) objects. And functions are no exception. They are called first-class objects. A first-class object is, quoting from Wikipedia:
In programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, modified, and assigned to a variable.
When you do something like:
admin.firestore()
You are getting the value returned by firestore. And it happens, that this returned value has a property on it named collection (a function).
However, when you do:
admin.firestore.FieldValue
You are accessing the FieldValue property on firestore.

Related

Where can I find the source code for the Javascript `typeof` operator?

I'm looking to see how the typeof operator in JavaScript knows that an object is a function.
To be precise, I'm wondering how I can take the function 'body' and reverse engineer it to determine what arguments it expects. The arguments property seemed close, but is only available within the evaluated function.
Neither uneval() or toSource() appear to do quite what I want, in addition to being obsolete.
The specification shows that:
Objects that do not implement [[Call]] are objects
Objects that do implement [[Call]] are functions
([[Call]] is an "internal property" of objects - it's not exposed directly to interactable running JavaScript)
So anything that can be ()d is a function. This will even include Proxies, since proxies can be called as if they were functions.
For the other question:
I'm wondering how I can take the function 'body' and reverse engineer it to determine what arguments it expects
The simplest method would be to turn the function into a string and use a regex to parse the parameter list:
function sum(a, b) {
return a + b;
}
const argList = String(sum).match(/\((.*)\)/)[1];
console.log(argList.split(/,\s*/)); // depending on how complicated the list is
// you may need to make the above pattern more elaborate

Understanding the JS code while setting up redis with Mongoose

I was trying to understand caching in NodeJS using redis.
In the lecture, the instructor told that best place to setup caching would be just before exec function in mongoose.
So in order to do that he did
const mongoose = require('mongoose')
const exec = mongoose.Query.prototype.exec;
//Redis logic
mongoose.Query.prototype.exec = function () {
console.log("i am here")
return exec.apply(this, argument);
}
1st: What will classify mongoose.Query.prototype.exec; as? value type or reference type? Because if it is a reference type then when we change mongoose.Query.prototype.exec = function then shouldn't its value change as well?
2nd I am unable to comprehend this line here return exec.apply(this, argument); Can someone explain this in stretch i.e this in apply points to where? and he is passing argument (this, argument); where does that Argument come from?
Can someone please help me out by answering both the above question?
What will classify mongoose.Query.prototype.exec; as? value type or
reference type? Because if it is a reference type then when we change
mongoose.Query.prototype.exec = function
exec is of reference type, but it is assigned the value of another reference variable mongoose.Query.prototype.exec. You can think of it like this : mongoose.Query.prototype.exec is itself pointing to an object (a Function object) in memory, and now after the assignment, exec is also pointing to the same object - in other words, the memory address of the object is copied (by value) from mongoose.Query.prototype.exec to exec during assignment. So the value of the variable mongoose.Query.prototype.exec itself i.e. the memory address stored in it, can be changed without affecting the other variable exec. They both will just end up pointing to two different objects.
Can someone explain this in stretch i.e this in apply points to where?
In this case, it'll be the object on which this function will be invoked i.e. the Query instance.
and he is passing argument (this, argument); where does that Argument come from?
Unless there is some code you missed to copy paste in the question, argument appears to be a typo. He was probably referring to the built-in object arguments which is accessible inside every function and consists of the arguments passed to the function. Here is a reference.
At a high level, what the instructor is trying to do is to override the built-in behavior of the function Query.exec() to add some of his own custom processing. He first creates a "backup" of the original function, then points Query.exec to his custom function which adds the custom processing (the log statement) and then hands over control to the backup i.e. proceed with built-in behavior. Whoever invokes exec() on a Query instance after this point will see the overridden functionality - first a log statement, then built-in behavior of exec()

Why is arrow function sent as a parameter when it simply returns the value it takes as is?

I am new to JavaScript and I am learning React using the following tutorial.
It also teaches to use Alt as a state management library and my question is related to the connect method syntax. I am not explaining the problem in detail as I believe my question is only related to understanding the syntax.
I understand that here connect passes comma separated parameters as props to the component App. I however do not understand the first parameter.
The arrow functions I have come across all use {} after => such as () => {}, where parameters will be in () and body of the function will be in {}
My understanding of ({lanes}) => ({lanes}) is that this is a function that takes an array of objects named lanes and returns the same array .The code snippet is as below:
export default connect(({lanes}) => ({lanes}), {
LaneActions
})(App)
My questions are:
Am I right that the first parameter is indeed a function?
is lanes enclosed in {} to specify it's an array? If no, what does it represent?
If 1. is right, why pass a function that passes the parameter as is. Why not write connect as connect(lanes,LaneActions)(App) or connect({lanes},LaneActions)(App)
Would enclosing lanes in {} make a difference and what is it?
If 1. is wrong please explain what the first parameter means.
Yes, that is indeed an arrow function.
No, that is not an "array" in JS (although if you've used PHP, you might mistakenly call it that, since the PHP community often uses "(associative) array" for this concept). That's an "object" in JS jargon, i.e., a key-value data structure (whereas in JS, arrays are numerically indexed). Specifically, the left-hand side is a new feature called "destructuring arguments", which takes an object and pulls out specific keys into local variables. On the right-hand side, there's an object literal, creating a new object based on local data (note that the value is omitted, a trick possible in recent JS).
Presumably because connect expects a callback as the first argument, and would break if you passed a non-function. Also, note that this isn't plain passthrough; it strips every key except lanes from the first argument, before returning it.
Since (1) is right, no answer needed here.
5 & 6: These are a bit broad. I'd recommend asking a new question or checking MDN's page on arrow functions if you want to find out all there is to know. To answer for this specific case: the () on the argument is needed because the arguments are more complex than a single identifier, the {} in the arguments are for destructuring, the () on the body is to distinguish between an object literal and a block consisting only of the single statement lanes, and the {} in the body creates an object literal.
If you're wondering exactly what the (somewhat densely-coded) arrow function does, by the way, it does roughly the same thing as the following (give or take a few currently-irrelevant quirks of arrow functions):
function(obj) {
return { lanes: obj.lanes };
}

What is the purpose of JavaScript's call and apply methods?

What is the purpose of call and apply methods in the language?
It seems to be an example of anti-pattern which breaks OOP principles. Or it just presents multi-paradigm approach?
This example made me to ask this question.
In one place of application (a part of library) there is such a code
socket.emit = function() {
if (!socket.banned) {
emit.apply(socket, arguments)
}
}
In another part of application (self written) there is such piece of code
socket.emit = function(arguments){
data = Array.prototype.slice.call(arguments);
emit.apply(socket, data);
}
In the first place the object should not work if it is banned. But the second part knows nothing about library logic and works independently.
How this situations may be resolved? We use libraries to ease the most difficult parts.
Function.prototype.call exists for one purpose only, and this is to allow the function to be called with a specific value of this, i.e. the one that's passed as the first parameter.
Function.prototype.apply is the same, but with the added advantage that the array passed as the second parameter is split out into multiple parameters when the function is invoked. This is useful when you want to call a function that takes a variable sized list of arguments but you have those arguments ready in an array instead of as individual values.
Take, for example, Math.max. If I have a set of unknown size and I wish to find the largest there are two approaches:
successively compare each element against the current maximum until you find the largest
pass all of them directly to Math.max.
I can't call Math.max(a, b, c, etc) because I don't know how many variables there are. Instead I can call Math.max.apply(null, myArray) and that gets expanded to Math.max(myArray[0], myArray[1], etc).
NB1: in ES6 .apply isn't strictly required any more because you can use .call with the ... spread operator, e.g. Math.max.call(null, ...myArray).
NB2: this has nothing to do with breaking OOP principles.

Example of Properties vs. Methods in JS

I found a great description of the semantic difference between Properties and Methods (paraphrased, via http://www.webdeveloper.com/forum/showthread.php?133712-Properties-Vs.-Methods):
Properties are like nouns. They have a value or state.
Methods are like verbs. They perform actions.
A property can't perform an action and the only value that a method has is the one that is returned after it finishes performing the action.
e.g.
Property: door; Possible Values: open, closed
Method: openDoor; Action: to change the value of the door property to "open"
Creating an example: I understand this in theory but I can't come up with an example. Would it be possible to show me how the door/openDoor would look in actual Javascript code?
Really, you need to back up and read some of the links posted above. But as a quick example:
var house = {} ;
house.isDoorOpen = false ;
house.openDoor = function(){
house.isDoorOpen = true ;
}
Here house is the object. It has a property: house.isDoorOpen. Here, it is more like an adjective. Either the door is open (true) or closed (false). As it sounds, it describes a property of the house.
Also, it has a method openDoor (which is used like this: house.openDoor() ). That's something that it can do. In this case, the action openDoor affects the isDoorOpen property, making it true.
Let's look at how the javascript spec ECMA-262 describes the term property
http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.26
4.3.26 property
association between a name and a value that is a part of an object
NOTE Depending upon the form of the property the value may be
represented either directly as a data value (a primitive value, an
object, or a function object) or indirectly by a pair of accessor
functions.
4.3.27 method
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.
Also
Javascript's definition of attribute is different from Java's
4.3.29 attribute
internal value that defines some characteristic of a property
for in, loops through an object's enumerable properties, and that includes its functions
http://eloquentjavascript.net/1st_edition/chapter8.html
"A function is called as a method when it is looked up as a property,
and immediately called, as in object.method()."
There does seem to be a more standard definition of property..
https://en.wikipedia.org/wiki/Property_(programming)#JavaScript
"A property, in some object-oriented programming languages, is a
special sort of class member, intermediate between a field (or data
member) and a method. .... Some object-oriented languages, such as
Java, don't support properties, and require the programmer to define a
pair of accessor and mutator methods instead."
In that more standard, non-javascript definition of property
C# has properties, and Java doesn't have properties
Object in JavaScript is just key-value pairs stored in a Hash. The difference between b/w property and method is that - property is a value stored in the hash key, whereas method is a function stored in the hash key.

Categories

Resources