javascript object assignment expression - comparison - javascript

Suppose we've got an optional parameter of a function which can come as undefined. Is there any difference between
options || (options = {});
and
options = options || {};
? If there is none, which one do you find better (I mean faster or more readable)? The question is - which one would you use to implement optional parameters in javascript?

Those exact 2 lines are different :
in the first one its an expression which do nothing with options ( if it is not defined) while the other is a statement.

Logically, they both are the same.
options || (options = {});
If options is a Truthy value, then it will short circuit and will not go to the next part. If it is a Falsy value, it goes to the next part where and empty object is created and assigned to options.
options = options || {};
The same thing, first right hand side is evaluated. If options is Truthy, it will be assigned as it is to options, if it is Falsy, an empty object is created and that is assigned to options.
Note: If options is an optional parameter of a function, and if it can accept other Falsy values, even if the user passes a Falsy value, intentionally, like false, 0, null, it will still use an empty object

Related

How does this unique() function work

As I was looking at a unique() function I found
which takes an array as argument and returns a new array which contains the unique elements of this array (which means no duplicated items). However I cannot understand the logic of this function. Can somebody explain it to me?
Here is the function:
function unique ( array ) {
return array.filter(function(a){
return !this[a] ? this[a] = true : false;
}, {});
}
I can't really understand the whole code especially the !this[a] ? this[a] = true : false; and the new object ({}) that is passed as the second argument to filter.
Let's start with the filter:
The filter() method creates a new array with all elements that pass
the test implemented by the provided function.
The a is the random number of the array to which you apply the filter. The whole essence is in the following statement:
return !this[a] ? this[a] = true : false;
If the this[a] is true, a has been already processed once and it has been added to this as one of its properties. Otherwise, this[a] is false. So taking its negation result in true and the current a should be returned. Furthermore this[a] would be set to true and then we proceed to the next a.
The following snippet will help you grasp what filter does:
var numbers = [1,2,3,4,5];
var filteredNumbers = numbers.filter(function(number){
console.log(number);
return number > 2;
});
console.log(filteredNumbers);
And the following snippet will show you in action what happens in unique function:
function unique ( array ) {
return array.filter(function(a){
console.log(this);
return !this[a] ? this[a] = true : false;
}, {});
}
var array = [1,2,3,1,2,3,4,5,5,6];
console.log(unique(array));
I understand the basic logic of filter but what i dont is the {}
passed as a 2nd argument and how each value is added to a new array
with !this[a]
The second argument is an optional value that you can pass to the filter method and it can be used as the this, when your callback would be executed (check the link I mentioned at the beginning about filter). You pass there an empty object. When you use the keyword this inside your callback, your refer this object. This is why the first time that code gets in this method returns {}. Check the first line of the output of the second snippet.
I will explain the second part of your question based on the second snippet. The first time you get in you have an empty object (I refer to this) and the first number processed is 1. So this1 would be undefined. So !this[1] would be true. Hence the first part after the ? is executed which is an assignment
this[1] = true.
Now this acquired its first key, 1, with value true. Furthermore, 1 would be returned from filter. The same happens with 2 and 3. When we arrive at 1 the
!this[1]
is false, since this[1] is true. So false is returned and the 1 now would not be added to the array that would be returned after all elements of array have been processed.
Basically, .filter would call the callBack function by supplying the individual values of the iterating array. If the callBack returns a value that resolves to true then that value will be collected, else that particular value will be ignored.
Here the second argument of filter has been used. That second argument will be used as a context(this) while calling the callBack internally. So here in your code, the passed object will be added with the array's value as property for each iteration. And in the consecutive iterations, the code will check the current value is available as a property in the initially passed object. If available then that ternary operator would return false, otherwise true.
Hence the unique values will be returned from the filter function.
Array.filter will only grab elements of the array when the function passed return truthy.
For each element of the array it is doing
return !this[a] // if value is not yet on this
? this[a] = true // add value to this and return true (grab element)
: false; // value was already cached, so return false (don't grab)
So it will only return 1 of each
Other answers have explained basically how this works. But a couple of points:
First, instead of return !this[a] ? this[a] = true : false;, it would be more concise to write
!this[a] && (this[a] = true)
Second, this code has the flaw that it only works on elements which can serve as keys into an object--basically strings or numbers. That is why using Set is better:
Array.from(new Set(array))
The above will work on any primitive or object.
Third, this approach does not work properly with strings and numbers. If the number 1 is present, it will filter out the string "1".
const uniq = a => a.filter(x => !this[x] && (this[x] = true), {});
console.log(uniq([1, '1']));
The reason is that object keys are string-valued.
Finally, IMHO this code is a bit too tricky for its own good. Most developers, even experienced ones, would stop and scratch their heads for a minute before figuring it out. Less experienced developers would have to consult the documentation for the thisArg parameter to Array#filter before being able to understand it. The ternary operator with the assignment inside is also a bit cryptic. I'd go ahead and write it out as
if (this[x]) return false;
this[x] = true;
return true;

ReactJS: Is it safe to use a conditional in the event of an undefined props?

I have an Immutable.Map with a couple of key value pairs.
Object {1: -200, 2: 13540}
<Component
items={this.props.items.get(key) || 0}
/>
The key may or may not exist in the map. In the case that it doesn't exist I just want to pass in zero to the component. It is a required props.
Is the conditional in there safe? What is a better approach if it's not safe?
A conditional is safe, but the way you have is ambiguous - you are likely going to get the result of the boolean expression, not the actual value.
I would do it like this to be explicit:
let val = this.props.items.get(key);
items={val ? val : 0}
This explicitly returns either val or 0, rather than the result of the boolean expression val || 0.
Your code looks like it's not going to compile just yet without some heavy modification, but yes you can certainly be doing that sort of thing.
The key is that Immutable.js does not throw an error on a missing key but returns the JS value undefined which is falsy, so undefined || 0 evaluates to 0 via the very-type-lax "if this first thing is truthy, return whatever it is, otherwise return whatever that second thing" behavior of ||.

use of OR in javascript object in my case confusion [duplicate]

This question already has answers here:
Javascript || operator
(5 answers)
Closed 8 years ago.
Question 1
What does options.left = options.left || _KSM.drawOption.left means? I know _KSM.drawOption is referring to the object (also a function), but how does the || operator work here? Does it mean if _KMS.drawOption.left is undefinded, assign options.left to options.left?
Question 2
Why the author didn't use this keyword in this case? I assume it's because in this demo he didn't create an instance, because he just do the calling once. Rigtht? (I've seen a lots of this in jquery plugin that's why I'm consufed when the author call the function name instead of this within a function)
Question 1
This is a way to set a default value to a variable. It actually evaluate the left side and if it is falsy, the variable will be equal to the right side (even if it is also falsy).
That is a bad way of assigning default variable especially when working with integer. 0 is considered as falsy, so you will never be able to assign 0 as a left property. Instead, it will always be the default parameter of _KMS.drawOption .
Question 2
We don't have the full code so we can only assume. But my assumption would be that draw is an event, a function bind with addEventListener. That mean the context (this value) is the target of the event. My guess would be a canvas.
Logical Operators in JavaScript work a bit differently than most people expect.
Logical OR (||)
Returns expr1 if it can be converted to true; otherwise, returns
expr2. Thus, when used with Boolean values, || returns true if either
operand is true; if both are false, returns false.
So instead of the expression resulting in a boolean value, it returns the first value that isn't "falsey". This has the benefit of being a great way to fill in default values in case it is undefined, null, 0, or an empty string.
var myObj = { name: 'Josh' };
myObj.age = myObj.age || 33;
Logical AND (&&)
Returns expr1 if it can be converted to false; otherwise, returns
expr2. Thus, when used with Boolean values, && returns true if both
operands are true; otherwise, returns false.
Basically just the opposite. Since any expression that evaluates to false will short circuit the logical check, it can be useful to test for the existence of a field, before trying to use it.
var myObj = null;
if(myObj && myObj.person && myObj.person.name === "Josh") // false, no error
var myObj = {};
if(myObj && myObj.person && myObj.person.name === "Josh") // false, no error
var myObj = {person: {}};
if(myObj && myObj.person && myObj.person.name === "Josh") // false, no error
var myObj = {person: {name: "Josh"}};
if(myObj && myObj.person && myObj.person.name === "Josh") // true
However! Caution should be taken here because in the case of both boolean values true or false and integer values 0 or anything not 0 you might end up overwriting a legitimate value.
Question 2: Not enough context

Meaning of || in javascript argument [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does “options = options || {}” mean in Javascript?
What is the meaning of the || in the second argument?
var obj = this;
var settings = $.extend({
param: 'defaultValue'
}, options || {});
Also would be nice if anyone knows how to search that character("|") here or in google! Thank you
That would be the logical OR. The statement will return the first truth-y value it finds.
In this case, if options is null (or any other value that isn't truth-y) it will evaluate to false. The || will then return the empty object.
That is some kind of fallback value or default value. So if the object is null or false the second value is used.
More importantly in that scenario, if options is not defined then an empty object {} is passed as an argument. Its kind of a side-effect use case of the logical OR operator. More specifically, it uses short circuiting. For example in the below case
a || b
if a is true then b never gets executed, but if a is false then b gets executed. Hence in the example you have shown, if options is not defined and thus false, then {} gets executed and thus passed as a parameter.
|| = or
As in the comparison operator.
|| = "OR". Example:
alert(false || false || false || "I'm valid!"); // alerts "I'm valid"
In your question, the example above demonstrates that the function requires an object for it's options. In this case, if the local variable "options" is not available, then just pass an empty object. Later, in the function that's being called, it's probably setting default values in that new object.

Reference and datatype checking, are these the same?

I have a simple function in my library that checks the validity of an object reference (object here meaning, a reference to a created HTML element, mostly DIV's). It looks like this:
function varIsValidRef(aRef) {
return ( !(aRef == null || aRef == undefined) && typeof(aRef) == "object");
}
While experimenting i found that this has the same effect:
function varIsValidRef(aRef) {
return (aRef) && typeof(aRef) == "object";
}
I understand there are some controversies regarding the short hand () test? While testing against various datatypes (null, undefined, integer, float, string, array) i could find no difference in the final outcome. The function seem to work as expected.
Is it safe to say that these two versions does the exact same thing?
No, in my opinion these functions don't work the same:
First option
If aRef is not undefined or null and the type of the var is object it returns true.
Second option
First we convert aRef to a boolean. Values like null, undefined and 0 become false, everything else become true. If it is true (so not one of those values) it checks if the type is object.
So the second option return false if aRef is 0, something you don't want. And it isn't option a elegant way to check it, because you check if an object or string or something is equal to a boolean.
And at least they don't return the same thing. The first option returns a boolean, but the second option returns the value you put in the function if (aRef) is false:
varIsValidRef(0);
>>> 0
varIsValidRef('');
>>> ""
varIsValidRef(undefined);
>>> undefined
varIsValidref(null);
>>> null
Because JavaScript use these values as falsy values you don't see the difference between these return values if you use if statements or something like that.
So I suggest you to use the first option.
they are strongly different:
!(aRef == null || aRef == undefined)
this part is evaluated to false with any of these "null", null, "undefined", undefined
(aRef)
while this other with any of these 0, "", false, null, undefined, NaN
Interesting case, but it seems logical for both to behave the same way despite being totally different. Lets see the first staement.
return ( !(aRef == null || aRef == undefined) && typeof(aRef) == "object");
Here,
null and undefined both denote a false state combined with the ! infront, makes it equal to the expression aRef which will return true in case both are either not null or not undefined.
They don't do the same, though they end up with the same results.
The first function is more strict in what it will count as false together, or if it's not, if its an object.
The second function will check if aRef is !false or not any of the falsy values (ie [], null, undefined) and check if the type is an object if it isn't.
I would prefer the first function, since its stricter in what it accepts, but if its all the same the function which performs the best should be used.
As for the controversy, its true that you have to be careful about how/when you use falsy values in equations but if it does what you want it to do (and for that you'll need to know what falsy values are) and you implement it correctly it should be no problem. The two are hard to put together though. So with that, if this does what you want it to do, and nothing more or less, by all means use it.

Categories

Resources