I have two HTML elements both with data-final-figure attribute on them. Either one of those final figure on the elements can be assigned a value or be left empty, but can NOT be set in conflict with each other. Now I'm using a quite inefficient way to:
1) check if the first one is null, if it's not null, then put it into a variable;
2) then check if the second one isnull, if it's not, and the first one is null, then copy it back to the first data-final-figure attr; if it's not null and the first one is not null either, then check if they are assigned an identical value, if not, then they are conflicting and here we throw an error because both elements are specified a different value. If the second is null and the first one is not, then copy the first one's value to the second.
I dimly remember this algorithm in one of the textbook but can't put my finger on the name. It's not Hanoi tower I'm sure. Is there a better way to implement? Thanks.
Your algorithm can be simplified. Here's pseudo-code:
var1 = elem1.attribute
var2 = elem2.attribute
if (var1 && var2 && var1 != var2) {
report conflict
} else if (!var1 || !var2) { // one is null
value = var1 || var2; // Get the non-null value
var1.attribute = var2.attribute = value // Assign it to both
}
Related
let's say that we have an javascript object like below:
let obj = {name: 'firstName'};
which is a better way to test whether a property exists on an object and is equal to something:
1)
if (obj.address === 'someAddress')
or
2)
if (!!obj.address && obj.address === 'someAddress')
Can someone explain which is better/safer and why?
You asked "safer" and "better". "Better" is subjective as long as you don't define what qualities you're looking for, so I'll ignore that part.
Accessing a property that doesn't exist is valid in JavaScript, and simply returns undefined. So the second way is equivalent to:
const address = obj.address
if (!!address && address === 'someAddress') {
...
}
Now you can see that that's plain silly, because the second condition implies the first. In other words, there is no way that address === 'someAddress' can be true and !!address can be false, so there is no need to do the first check at all.
So the second approach is not safer than the first. Both have the same observable effect.
Nitpicker's corner: if you were checking for some falsy value like 0 or "" instead of the truthy string 'someAddress', then the second approach would not even work, because both conditions can never be true at the same time.
Also, if address is a property with an evil getter that may return a different value each time it's called, all bets are off. The first version could actually be safer because it only gets the value once, but presumably the value would be used inside the if block so the code is still broken.
1 is shorter :D and it works :D
Better is:
if (obj?.address === 'someAddress')
it checks both conditions
I am fairly new to JavaScript and am going over some code. However there is one bit i am unsure about.
product = product !== null && product[0] !== null && product[0].id || "";
Where product is an array. Could someone please help me understand what this does. Any help would be much appreciated. Many thanks =)
One way to understand what this does it to run it and observe the result.
Here's a JSBin showing 3 examples - which produce a different outcome, depending on the initial value of product - https://jsbin.com/roruvecubi/edit?js,console
To further clarify this with an explanation...
It will attempt to evaluate that all the following premises are true at the same time and re-assign product to the value of id of the first object found (if these are found) or an empty string if otherwise.
product array is NOT null
AND
First element of product array is NOT null
AND
First element of product array is an object containing a truthy key-value pair with key id. I.e. First element could like this:
{
id: "someValue" // product[0].id would be a truthy value in this case
}
AND
If 3.0 is true - assign value of id. If 3.0 is NOT true (id: does not contain a truthy object, array, number, string, true - Google the precise definition of truthy), then just assign empty string "" and thus result will be product = "";
product !== null it checks if product is null if it is it will stop right here and not do the other calculations (this is practiced so you won't get undefined, in this case, hmm null)
product[0] !== null checks if null, so when .id you won't get an error can't find id of undefined / null
let usr = null
console.log(usr.id)
GIVES ERROR Uncaught TypeError: Cannot read property 'id' of null
enter code here
With a few words, these are some practices to check if the VARIABLE has unwanted values to stop the calculations right there and not get errors.
Some prefer to try catch v--
[wasn't sure how to word this question exactly, but] say I have some code:
var myValue = 6;
var newValue = myValue == 6 ? myValue : 3;
notice that I'm using the ternary operator to check if a variable fulfils a certain condition, and if so, then I set my newValue to that variable, and if not, something else.
So the (slight) problem:
In a case like this, I have to actually write the variable name twice (myValue == 6 ? myValue : ...), this usually isn't a problem, but say I have a very long variable name, or even the property of a certain array or something else I don't want to manually write out, or even make a new variable; I just want to set the new variable equal to the value of the variable in the condition.
If my condition is simply if the expression exists, then I could obviously do:
newValue = myValue || 3;
but if I'm checking any other condition, I have to write the checking-variable twice, so is there any way to access the ternary's condition text, at least, or even an array of the variables involved in the condition so I have some kind of hope to access it, or is there any other way to do one-line conditions like this, without assigning a new variable?
Let's say I have the following code:
var t = $("#objectID").html();
Checking that t is defined and has a proper value is easy.
if (typeof(t) === 'undefined' || t == null || t == '')
t = 'something else';
OR
var t = $("#objectID").html() || 'something else';
My question is though, what if you have something like the following: How would would you check it for undefined values before continuing?
$("#object").find("element").html().replace(/ |t/g, '').trim();
How do I ensure that each part of the object is legitimate before continuing down the line without having a large block of checks?
What if there's many things similar to .replace and .trim, like 10 or so? How do you check for each one?
You can use the function parameter of .html()
$("#object").find("element").html(function(html){
return ((html || 'Something').replace(/ |t/g, '') || 'Something else').trim();
});
So, what you are doing is first you're checking html has value and give it some default value if it doesn't have one. Then you group the returned string from replace and check if it has truthy value or give it a default value too and then trim it.
Here's how I would do that, checking as needed.
var element = $("#object").find("element");
var t = element.length ? element.html() : '';
t = t.replace(/ |t/g, '').trim();
First step is making a variable called element to save the jQuery object. Anytime you use the same jQuery search more than once, it's a good idea to save it to a variable: it avoids repetition and speeds up performance.
The next step is calling jQuery's length method to test if it really found any HTML elements. If either "#object" or "element" are not found, element becomes an empty jQuery object with a length of 0, and 0 is considered false in a JavaScript conditional check.
If the length of element is at least 1, then we know it's legitimate, and call safely html() on it.
If length is 0, then t is just set to an empty string. Checking length was necessary because calling html() on an empty jQuery object would have returned undefined instead of a string and caused an error.
I used the ? conditional operator for brevity but you can do the exact same check with an if statement
var element = $("#object").find("element");
if (element.length) {
var t = element.html();
} else {
var t = '';
}
t = t.replace(/ |t/g, '').trim();
I like making t default to an empty string, to ensure the variable is always a string. That way I can call replace() or trim() or any other string method with it.
An empty string also evaluates to false in JavaScript conditions, making it easy to check later on.
if (t) {
doSomethingWith(t);
}
I want to extract a value from a variable. If its an array, I want the first element, and if not, I want the value of that variable. The value is a float, but I was wondering which of these are better in terms of performance, portability to non-floats, and of course short code and code readability
I want to use
value = variable[0] || variable
Its short and nice, is there any caveats is using this?
or I can do,
value = ([].concat(variable))[0]
This SO question says it's bad for performance.
And then, ofcourse, I can check if variable is an array or not in a few different ways, that is also mentioned in above question. Is there any better ways if the first one is not good?
Your value = variable[0] || variable will work, and will work reliably. Technically, if variable is a number primitive, what the JS engine has to do at that point is promote it to an object and then look up the 0 property on that object, but as you know it won't have one, that's okay.
The only cases where that may fail are if variable is null or undefined, because neither of those can be promoted to an object, and so the expression will throw. Provided you're okay with that, then you can use that. I'd comment it, though, because it's pretty odd-looking.
If you needed to defend against null and undefined, you could use the fact that == null will filter out both of those:
value = variable == null ? undefined : variable[0] || variable;
I'd comment that, too. :-)
Having this
value = variable[0] || variable
you may go to a trouble if the first element of the array is false. For example:
var arr = [false, 1, 2, 3];
value = variable[0] || variable; // <--- value is [false, 1, 2, 3]
So, I'll go with this:
var value = arr instanceof Array ? arr[0] : arr;
If you are not sure if the array is full then you should add one more check.
var value = arr instanceof Array && arr.length > 0 ? arr[0] : arr;