Generating a unique ID in javascript. Understanding this code - javascript

Here is a code snippet i've come across for creating uniqueIDs in a script.
var now = (new Date()).valueOf();
var future = (new Date()).valueOf();
while(future == now){
future = (new Date()).valueOf();
}
return future;
My question is, why use .valueOf() instead of .getTime() and is the purpose of two date objects and a while loop to avoid the change of returning the same values if called multiple times. Surely the chances of returning the same millisecond representation of the date are slim to none? Any thoughts?

As you stated, the chance of getting back the same uuid is small - but not impossible. There is no real need to use valueOf instead of getTime. Also there are way better algorithms for generating UUIDS see https://github.com/pnegri/uuid-js for well tested implementations which are also time based.

I would personally use .getTime() method adding some kind of basic operation, such a pseudo-aleatory number generation added to the returned quantity in milliseconds. Simply because a millisecond is not 100% a reliable output, as Dan Pichelman said, "You'd be surprised how much you can do in a millisecond these days".

Related

Is the IF function removing the date object in javascript?

I've spent an hour looking for answers and trying different things so I appreciate any help here.
The following code works great for finding someone's part B effective date. However, when someone's birthday is really on the 1st of a month the 'if' function get's used, and I'm no longer able to format and write the date. It's almost like 'partB_eff' is no longer a date object. (I'm a newbie, so I might just be making this part up.)
I'm getting the error "TypeError: partB_eff.toLocaleDateString is not a function at AutoFill_6_Step_Checklist(Code:24:27)"
How can I resolve this?
let birthday = new Date(e.values[2]);
//this is a date entered from a google form
let bdayCopy = new Date(birthday);
//I created this since I'll be using .setMonth(), and I don't want to change the original date of the birhtday
let bday65 = new Date(bdayCopy.setMonth(bdayCopy.getMonth()+780));
//finds the 65th birthday
let partB_eff = new Date(bdayCopy.setDate(01));
//find's the Medicare part B effective date (the 1st of the month someone turns 65)
if(birthday.getDate()==1){
partB_eff = partB_eff.getMonth-1;
//if the person's birthday is really on the 1st of the month, the part b effective date is the 1st of the month prior. partB_eff must be converted
}
partB_eff = partB_eff.toLocaleDateString('en-us',{year:"numeric",month: "short",day:"numeric"});
//format partB_eff so that it looks nice on paper
partB_eff = partB_eff.getMonth-1;
Doesn't do what you think it does. What it does is get the vound function getDate from your date object, and attempt to subtract one from it. In any other language trying to do subtraction on a function would be a type error, but Javascript is Javascript and allows numeric operations on almost any type. A function minus a number in JS is NaN. NaN doesn't have a method called toLocaleString, hence the error.
What's interesting is that you did the same operation correctly above with bdayCopy.setMonth(bdayCopy.getMonth()+780)
Just do the same thing here
bdayCopy = new Date(bdayCopy.setMonth(bdayCopy.getMonth()-1));
Also some important concepts. if in Javascript is not a function. if is a keyword that starts a conditional statement. You can't do any of the things you can do with a function with if. You can't call it or assign it to a variable or pass ot as a function argument. Clearly understanding what a function is is something you need to do to be able to work in JS, or frankly any other language.
Finally if you are doing date math in JS I strongly recommend you use a date library like DateFns or Moment. Javascript native date APIs are possibly the worst designed date API of any language ever.

Javascript Int vs BigInt libraries

From the JavaScript documentation we see that, due to using double-precision floating-point format numbers, to go beyond 9007199254740991 a library is needed.
We'll find a handy list of libraries to achieve that here.
While searching on homomorphic encryption I came across this question.There you can find this link to an in-browser implementation of Pailler.
After inspecting the code I saw the source included jsbn.js which made total sense (as you are gonna need BigInts for the crypto). However, the way it deals with the numbers to be encrypted looked a bit odd to me.
$('#btn_encrypt').click(function(event) {
var valA = parseInt($('#inputA').val()),
valB = parseInt($('#inputB').val()),
startTime,
elapsed;
startTime = new Date().getTime();
encA = keys.pub.encrypt(nbv(valA));
elapsed = new Date().getTime() - startTime;
$('#encA').html(encA.toString());
$('#encAtime').html(elapsed);
From using parseInt and nbv function nbv(i) { var r = nbi(); r.fromInt(i); return r; } it seems clear that they are relying on integers to create the BigInt that will then be encrypted.
Does that make any sense at all? Even less so when having a function to create BigInts directly from strings // (protected) set from string and radix
function bnpFromString(s,b) { ...} That link has been referenced in several other answers both in here, and the crypto site and as I said I am a newbie at JS so I wanted to check whether this is indeed an contraindicated way of implementing Pailler or I have understood something wrong.
Thanks a lot for helping out!
It appears that the Pailler implementation you linked to is intended as a proof-of-concept demo rather than as a full-fledged implementation. Presumably, the author intended it for use only on toy examples such as (36+14)*7 or (97+5)*11 rather than "real" examples involving hundreds of digits.

javascript performance for Array

i tried to figure out, what is different between two versions of a small code-snippet in execution. Do not try to understand, what this is for. This is the final code after deleting all the other stuff to find the performance problem.
function test(){
var start=new Date(), times=100000;
var l=["a","a"];
for(var j=0;j<times;j++){
var result=document.getElementsByTagName(l[0]), rl=result.length;
for(var i=0;i<rl;i++){
l[0]=result[i];
}
}
var end=new Date();
return "by=" + (end-start);
}
For me this snippets takes 236ms in Firefox, but if you change l[0]=result[i]; to l[1]=result[i]; it only takes 51ms. Same happens if I change document.getElementsByTagName(l[0]) to document.getElementsByTagName(l[1]). And if both are change the snippet will be slow again.
After using Google Chrome with DevTools/Profiles I see that a toString function is added when executing the slow code. But i have no chance to get which toString this is and why it is needed in that case.
Can you please tell me what is the difference for the browser so that it will take 5 times longer than the other?
Thanks
If you only change one of the indexes to 0 or 1, the code doesn't do the same thing anymore. If you change both indexes, the performance remains identical.
When using the same index for reading and writing, what happens is that the value stored in l[0] is used in the next call to getElementsByTagName, which has to call toString on it.
In the code above you use l[0] to search for an element. Then you change l[0] und search again and so on. If you now change only one of the two uses (not both!) to l[1], you don't change what you are searching for, which boosts the performance.
That is why when you change both it is slow again.

Partial garbage collection of objects possible? (server-side JS)

Assume a server-side JavaScript environment, that provides a function like so:
var parseIsoDuration = /... complex regex .../
function dateDiff(date, isoDurationStr){
var duration = parseIsoDuration.exec(isoDurationStr);
return timeLibrary.add(date, duration);
}
That function will be called from outside, on hundreds of dates, but mostly the same ISO duration. Because RexExp parsing is not a cheap operation, an application-level cache could be implemented:
var parseIsoDuration = /... complex regex .../
var durationCache = {}
function dateDiff(date, isoDurationStr){
var duration;
if (durationCache[isoDurationStr] === undefined){
duration = parseIsoDuration.exec(isoDurationStr);
durationCache[isoDurationStr] = duration;
} else {
duration = durationCache[isoDurationStr];
}
return timeLibrary.add(date, duration);
}
The problem: the server may run for a year straight, and the cache object never goes out of scope. If the function is called with a lot different ISO duration strings, the cache will grow over time and never reduce its size.
Is there a way to tell V8 that it may clear "old" entries from the cache object as needed (i.e. has grown too large)? Or at least make it clear it entirely as the need arises? (Solution may depend on ES6/7 features)
ES6 WeakMaps sound interesting, but they accept objects as keys only. Wrapping a string in an array to make it an object will not work, because doing that again will result in a different object. I would need something like Symbol(str), but that returns an identical reference for two identical inputs (Ref(str) === Ref(str)).
edit: There's actually Symbol.for("str") === Symbol.for("str"), but it's not accepted as WeakMap key.
I'm also not sure when entries would actually be garbage-collected in case of a WeakMap - it might be more or less immediately, because there would be no reference to the object right after it was added to the WeakMap. So a double no.
Unsetting individual keys would require additional book-keeping when they were added and some algorithm to determine a sensible TTL.
Is it necessary to cache the RegExp results even? Is there some built-in cache? For literal expressions or if created via constructor only, or both?
What you are talking about sounds like Java's SoftReference and no, there is nothing like this in v8. Instead you should manage cache yourself or use one of the modules like lru-cache

Better to use declarations or self to modify variables

This is probably a stupid question, but im wondering which is better practice for JS
var expireDefault = new Date();
expireDefault.setYear(expireDefault.getFullYear() + 1);
This is how i am getting next years date at run time.
I have been told however to use a seperate Date() decleration.
var today = new Date();
var expireDefault = new Date();
expireDefault.setYear(today.getFullYear() + 1);
Is this necsecary ? Or does it even matter ?
In my opinion from this example i dont circular reference.
But the principles remain the same.
The two are equivalent.
The second one is just uselessly verbose and heavy. Don't use it : it hides the simplicity of what is done.
The second one is only necessary if you want to use later today's date. If not, you are unnecessarily using memory to store a Date object and so, first option is better.
I would prefer the first approach, it reads better, but that's just an oppinion. Take a look at momentjs, which is an amazing lib dealing with dates.

Categories

Resources