calling a function with a different way on native JS - javascript

I am looking for a solution for the basic structure of my code. I am trying to use less parenthesis or words. I don't know if there is a way or not but I want to ask :)
I am trying to create a dynamic object which changes when some other stuff changed. Basically, I have to use a function. I am here to abridge the way that I use.
Let me give you a working solution:
function mainFunction(object){
// getElementById(object.id)
// use object.date
// use object.string
}
mainFunction (function(){return{ id:"varName",date: Date.now(), string:"test2" }})
On this sample I am not happy with this commands:
mainFunction (function(){return{
}})
Now, question 1:
Is there a way to use a short way to create a dynamic object?
//expected code
mainFunction{ id:"varName",date: Date.now(), string:"test2" };
-> date must be redefined on everytime that I call the object.
-> using date.now in quotation marks and call it with eval or Function isn't making sense.
Question 2:
is there a way to use the varName on the beginning even it is undefined?
//expected code
varName.mainFunction (date: Date.now(), string:"test2");
// expected result
{
if (typeof varName !=="undefined"){
//create it.
}
// call the main function.
}
-> try, catch etc. don't work on here. Because I don't want to use try on the main code.
Thank you so much,

If I'm understanding you correctly, you can use accessor properties to do the parentheses part of what you're asking about. I wouldn't call it good practice in this situation (a function call should generally look like a function call, not a property access), but if you want to:
function mainFunction(object){
const first = object.date;
console.log(first);
while (object.date === first)
; // Busy loop for up to one millisecond
console.log(object.date);
}
mainFunction({
get date() {
return Date.now();
}
// get string() { etc.
});
Notice how object.date triggers a function call to the get function for the date property on object, and so the value changes as the time changes.
I can't figure out the question about varname, but fundamentally varname.mainFunction with varname having the value undefined will always fail, and you can't do anything in mainFunction that will prevent that.

Related

How to provide only second parameter to function typescript? [duplicate]

This question already has an answer here:
How to use Optional Parameter and Rest Parameter together in Typescript?
(1 answer)
Closed 5 months ago.
Say i have a function like this one in typescript:
openMultipleAddFormModal(commission?: Commission, people?: People): void {
// some data
}
As of my understanding i added the Optional Chaining operator to make a parameter non necessary.
How do i change my code above to have something like this?
this.openMultipleAddFormModal(res); // where res here refers to people and NOT to commission
Can i do something like c# does, where you can provide the name of the parameter when calling the function and "binding" that to the property?
Something like this in C#:
// main method
public void UpdateBase(string machineRef = null, string userRef = null){
Ref = machineRef ?? Environment.MachineName;
UserRef = userRef ?? Environment.UserName;
}
// and then i specify the parameter i am passing
UpdateBase(userRef: userRef); // is there something like this in typescript / javascript?
Thanks for any help!
To "skip" the argument for an optional positional parameter in JavaScript and TypeScript, you pass undefined as the argument for the parameter:
openMultipleAddFormModal(undefined, peopleObject);
If you're really into brevity, you could use void 0 instead of undefined (the void operator's result is always undefined), but frankly it suffers in terms of readability...
Playground link
There's been discussion of allowing arguments to be simply skipped by writing fn(, second), but it's never reached the point of progressing through the JavaScript proposal process.
There aren't named parameters in Typescript or Javascript.
So the only way you could achieve this is to pass the arguments as an object, so both the parameters can be marked as optional.
But you can pass undefined as the first argument if you want, which behaves like not passing the argument. But I personally like the approach below when I encounter a situation like this because I like the ergonomics.
instead of this,
openMultipleAddFormModal(commission?: Commission, people?: People): void {
// some data
}
do this,
openMultipleAddFormModal(params: {commission?: Commission, people?: People}): void {
// access like
console.log(params.commission)
}
You can even destructure right in the function definition if you want like this
openMultipleAddFormModal({commission, people}: {commission?: Commission, people?: People}): void {
// access like
console.log(commission)
}
and when calling the function, do it like this,
this.openMultipleAddFormModal({people: res})
I'm not an expert on this subject but I don't think there's any downside to this approach other than maybe a few milliseconds of more time execute (Which won't ever be noticeable enough).

using Set.has in Array.filter - incompatible receiver

Suppose I've a Set as a lookup table.
const myset = new Set(["key1", "key2", "key3", "keepMe"]);
I wanted to filter another array of some other keys (say mykeys) which are in myset.
const mykeys = ["ignoreMe", "keepMe", "ignoreMeToo", "key2"];
Question:
Why do I have to use
const filtered = mykeys.filter(k => myset.has(k))
instead of
const filtered = mykeys.filter(myset.has)
// TypeError: Method Set.prototype.has called on incompatible receiver undefined
i.e., why do I've to create an anonymous lambda function in filter? keys.has has same signature (argument - element, return boolean). A friend told me it's related to this.
Whereas mykeys.map(console.log) works without error (although not being of much use).
I came across this article at MDN and I still don't get why "'myset' is not captured as this". I understand the workaround but not the "why". Can anyone explain it with some details and references in a human friendly way?
Update: Thank you all for the responses. Maybe I wasn't clear about what I'm asking. I do understand the workarounds.
#charlietfl understood. Here's his comment, the thing I was looking for:
Because filter() has no implicit this where as set.has needs to have proper this context. Calling it inside anonymous function and manually adding argument makes the call self contained.
You could use thisArg of Array#filter with the set and the prototype of has as callback.
This pattern does not require a binding of an instance of Set to the prototype, because
If a thisArg parameter is provided to filter, it will be used as the callback's this value. Otherwise, the value undefined will be used as its this value. The this value ultimately observable by callback is determined according to the usual rules for determining the this seen by a function.
const
myset = new Set(["key1", "key2", "key3", "keepMe"]),
mykeys = ["ignoreMe", "keepMe", "ignoreMeToo", "key2"],
filtered = mykeys.filter(Set.prototype.has, myset);
console.log(filtered);
This is a fundamental design decision dating back to the first definition of the JavaScript language.
Consider an object
var myObjet = {
someValue: 0,
someFunction: function() {
return this.someValue;
}
};
Now, when you write
var myValue = myObject.someValue;
You get exactly what you have put in it, as if you had written
var myValue = 0;
Similarly, when you write
var myFunction = myObject.someValue;
You get exactly what you have put in it, as if you had written
var myFunction = (function() {
return this.someValue;
});
...except now, you are not in an object anymore. So this doesn't mean anything. Indeed, if you try
console.log(myFunction());
you will see
undefined
exactly as if you had written
console.log(this.someValue);
outside of any object.
So, what is this? Well, JavaScript decides it as follows:
If you write myObject.myFunction(), then when executing the myFunction() part, this is myObject.
If you just write myFunction(), then this is the current global object, which is generally window (not always, there are many special cases).
A number of functions can inject a this in another function (e.g. call, apply, map, ...)
Now, why does it do this? The answer is that this is necessary for prototypes. Indeed, if you now define
var myDerivedObject = Object.create(myObject);
myDerivedObjet.someValue = 42;
you now have an object based on myObject, but with a different property
someValue
console.log(myObject.someFunction()); // Shows 0
console.log(myDerivedObject.someFunction()); // Shows 42
That's because myObject.someFunction() uses myObject for this, while myDerivedObject.someFunction() uses myDerivedObject for this.
If this had been captured during the definition of someFunction, we would have obtained 0 in both lines, but this would also have made prototypes much less useful.

Can't use String.prototype.match as function for Array.some?

This doesn't work:
var s = '^foo';
console.log(['boot', 'foot'].some(s.match));
Uncaught TypeError: String.prototype.match called on null or undefined
But this does:
var s = '^foo';
console.log(['boot', 'foot'].some(function(i) { return i.match(s) }));
Why is this? I imagine somehow the String.prototype.match function is too "primitive" or something, but why exactly? Since I'm not using ES2015, the second version seems quite verbose. Is there an alternative?
EDIT
When I wrote the above, I actually got it backwards compared to my actual need, which was matching one string against a number of regexes. But thanks to the great answers and comments below, I get it: [/^foo/, /^boo/].some(''.match, 'boot').
Note: The value of this is determined by how the function is called! (exception: bound and arrow functions)
If you pass s.match to .some, then the function will be called with this set to the global object (e.g. window) not the string it "belongs" to.
I.e. it would be equivalent to this:
String.prototype.match.call(window, 'foo')
This cannot work because this has to refer to a string object.
You could solve this by binding the function to a specific this value:
['boot', 'foot'].some(s.match.bind(s));
Learn more about this:
MDN - this
You Don't Know JS: this or That?
How to access the correct `this` context inside a callback?
A function value in Javascript does not bring its object along with it. The value of s.match is a plain function value, with no knowledge that you happened to find it attached to s. In fact, no matter what String you access it through, it's always the same function value:
"foo".match === "bar".match
//= true
When you call a function through an object, Javascript sets this to that object for the duration of the function call. But as soon as anything comes between retrieving the function value and calling it, any object association is lost.
You can create a function that does remember a specific this value using bind, as in #Felix King's answer. someFunction.bind(someObject) has approximately the same meaning as function(arg1, arg2,...) { return someObject.someFunction(arg1, arg2,...); }, but it automatically handles the number of parameters properly.

why write a function that never returns a value

I am reading a very comprehensive javascript programming book. In the "functions" section of language basics I have come to the following:
"The return statement can also be used without specifying a return value. When used in this way, the function stops executing immediately and returns undefined as its value. This is typically used in functions that don’t return a value to stop function execution early, as in the following example, where the alert won’t be displayed:"
function sayHi(name, message) {
return;
alert(“Hello “ + name + “, “ + message); //never called
}
I am trying to understand why anyone would want to do this. Why write a function that returns "undefined"? I have tried googling, and searching SO, but have not had much luck though this may be because I am not phrasing my search correctly as I am learning js.
Can anyone give me a real-world example of where this might be useful so that I can understand?
Usually it's a conditional return. Something like
function calculateSomething(obj, condition) {
if (condition !=0 ) return;
obj.data = obj.data * 42;
}
in this case if some condition fails - function exits right away. Otherwise data in a passed object is modified.
The function you provide is useless...
However, not every function needs to return something. Sometimes a function does things "elsewhere" and the value that is returned is irrelevant.
The function may have side effects, such as altering the state of the page. Then, the caller may not expect any return value.
In my opinion, learned from masters so to speak, the idea here is to only temporarily disable the function. So if you have like an x amount of function calls to sayHi() like for example in a repeater or spread out over multiple files, the idea can be useful to simply return; without a value. Useful? Yes, to avoid commenting out chunks of code, but that's it.
Leaving this in a development environment, which initially will enter the www, you should not write it like this, and always make sure that: when a function has to return "something", then "something" always counts for value, no matter what the condition. With lowest value a boolean => return false;. This counts for every code block inside that function => for if else while ...
/* INCORRECT: it only returns something conditionally */
function do(something){
if (condition){
return false;
}
}
/* CORRECT: it returns value no matter what the condition */
function do(something){
if (!condition){
return true;
}
return false;
}
/* OPTIMIZED: a lot of ideas can be optimized, especially when returning booleans */
function do(something){
return !condition;
}
The rules only apply if you want to write proper code. Using tools like jslint, jshint or re-sharper helps a lot in understanding the basic principles of writing ecmascript valid code. Since not everyone is aware of these rules, all examples will yield the same result. In the sens of "it works, but it's not valid code".
Because A JS function is an object(has:Attributs+methods)
And , An object should have a value which can be undefined .
The proof is that
function sayHi(){}
Can be handled such as object even calling it :
var returnedValue=sayHi.call() ;
If sayHi does not return anything, returnedValue will be undefined
Example if you want to use classes I am sure about it you will use setter functions to give value for an instance attribute.
Like this:
function Something(val) {
this.value = val;
}

My javascript constructor function method returns the entire method as text, instead of the expected return value

I am new to constructor functions, and I have the following in a .js file I include:
// should just get the number of customers out of the passed-in object
function myCustomers(customerObj) {
this.customerCount = function(customerObj) {
return customerObj.length;
};
}
On the .htm page which includes the .js file, I have the following:
var tmpObj = new myCustomers(custObj);
alert(tmpObj.customerCount);
What I expected was the alert to give me the number of customers, such as "1", etc. Instead, the alert contains the entire text of my function as though it were a string, like this:
function(customerObj) {
return customerObj.length;
}
I'm sure this is simple, but I have had a tough time googling for an answer, since my search contains very generic words like function, text/string, method, etc. FYI, this example has been pared down from a more complicated function, to hopefully make it easier to understand the question. I have tested this simpler function with the same result.
Thanks in advance!
It looks like in your alert, you are not actually calling the function, but instead passing the function itself to alert(). Try this:
alert(tmpObj.customerCount(custObj));
You might also want to change your myCustomers object to hang on to the object that is passed into the constructor, so you don't have to pass it in again when you call the function.
You should call the method like this:
var tmpObj = new myCustomers(custObj);
alert(tmpObj.customerCount(custObj));
Note the method parenthesis ;)

Categories

Resources