I have a function with 2 parameters, it should work whether a the 2nd parameter is assigned or not in the bracket. Basically, if it's assigned then do something if not do something else or just don't bother about it.
vf.showHide = function (trigger, target) {
var $trigger = $(trigger),
trigParent = $trigger.parent(),
trigDataView = $trigger.data('view'),
numShown = $trigger.data('showalways'),
basketSubtotalElem = $('.subtotal .monthlyCost span.price, .subtotal .oneOffCost span.price, .subtotal label h3, .vat *');
target = target || null; // This is the 2nd parameter but I don't know if this right...
trigParent.delegate(trigger, 'click', function (e) {
var elem = $(this);
target = $(elem.attr('href'));
e.preventDefault();
if (trigDataView === 'showhide') {
if($('.filterBlock')){
if (target.is(':visible')) {
target.hide();
elem.find('span').removeClass('minus').addClass('plus');
} else {
target.show();
elem.find('span').removeClass('plus').addClass('minus');
}
}
}
});
}
So if the function is called like this: vf.showHide('a', 'div') it works and if it's called with 1 parameter like this: vf.showHide('a') it's should still works and error is thrown.
Many thanks
When you invoke a function, if you pass fewer parameters than expected, the parameters you omit are given the undefined value. So in your case:
vf.showHide = function(trigger, target) {
if (target === undefined) {
//target parameter is not passed any value or passed undefined value
//add code to process here, e.g. assign target a default value
}
}
target = target || null: if target is evaluated to false, it's assigned to null. Take notice that empty string, zero number (0), NaN, undefined, null, false are evaluated to false. So please be careful to write code like that.
target = target || null will work.
What you are doing here is declare an local variable within the function's scope.
Within each function, a local variable corresponding to the the name of the parameters are created to hold the passed in value.
If the parameters are not passed in, it will remain as 'undefined' local variable.
function (a, b) {
//a, b are declared.
}
what target = target || null does is just assign a value to an declared local variable it use the || expression:
The value of of || expression is determined by the first operands return true.
true || 2 will be valued as true
false || 2 will be valued as 2
Related
I have created a module and defined functions in it. Sometimes I need to check if a certain function is actually already created.
For example
var newyork = function() {
console.log("newyork");
};
var washington = function() {
console.log("washington");
};
exports.newyork = newyork;
exports.washington = washington;
Now in the different file, I want to first check if the function exists, something like:
var cities = require('./city');
if(cities.newyork) {
console.log("city function exist");
}
else {
//false
}
As I said in the comments what you wrote actually works because
if(cities.newyork){
Checks if cities.newyork is truthy. The following things are truthy:
functions (thats why it works here)
numbers except 0
strings except an empty one
objects / arrays
If it is however not defined, cities.newyork will be undefined which is falsy (will enter the else branch)
typeof cities.cityName === 'function'
if city's name is assigned to some variable
typeof cities[cityName] === 'function'
In my JavaScript I want to check whether the element with specific id is exist or not, I tried it with 2 ways
1).
var myEle = document.getElementById("myElement");
if(myEle == null){
var myEleValue= document.getElementById("myElement").value;
}
2).
if(getElementById("myElement")){
var myEleValue= document.getElementById("myElement").value;
}
but it gives same error as below -
Object expected
var myEle = document.getElementById("myElement");
if(myEle) {
var myEleValue= myEle.value;
}
the return of getElementById is null if an element is not actually present inside the dom, so your if statement will fail, because null is considered a false value
You can simply use if(yourElement)
var a = document.getElementById("elemA");
var b = document.getElementById("elemB");
if(a)
console.log("elemA exists");
else
console.log("elemA does not exist");
if(b)
console.log("elemB exists");
else
console.log("elemB does not exist");
<div id="elemA"></div>
getElementById
Return Value: An Element Object, representing an element with the specified ID. Returns null if no elements with the specified ID exists
see: https://www.w3schools.com/jsref/met_document_getelementbyid.asp
Truthy vs Falsy
In JavaScript, a truthy value is a value that is considered true when evaluated in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN). see: https://developer.mozilla.org/en-US/docs/Glossary/Truthy
When the dom element is not found in the document it will return null. null is a Falsy and can be used as boolean expression in the if statement.
var myElement = document.getElementById("myElement");
if(myElement){
// Element exists
}
You need to specify which object you're calling getElementById from. In this case you can use document. You also can't just call .value on any element directly. For example if the element is textbox .value will return the value, but if it's a div it will not have a value.
You also have a wrong condition, you're checking
if (myEle == null)
which you should change to
if (myEle != null)
var myEle = document.getElementById("myElement");
if(myEle != null) {
var myEleValue= myEle.value;
}
document.getElementById('yourId')
is the correct way.
the document refers the HTML document that is loaded in the DOM.
and it searches the id using the function getElementById()
which takes a parameter of the id of an element
Solution will be :
var elem = (document.getElementById('myElement'))? document.getElementById('myElement').value : '';
/* this will assign a value or give you and empty string */
Use typeof for elements checks.
if(typeof(element) === 'undefined')
{
// then field does not exist
}
if( document.getElementById("myElement") ){
console.log('exists');
}
or shorter way
if( document.querySelector("#myElement") ){}
this works for me to check if element exits
let element = document.getElementById("element_id");
if (typeof(element) !== 'undefined' && element!== null)
{
//content
}
Optional Parameters
I often have JavaScript functions with optional parameters.
Instead of writing a long check like this:
if(param === null || param === undefined){
param = {};
}
I usually use the following syntax:
function doSomething(optionalParam, optionalCallback, optionalFlag){
optionalParam = optionalParam || {};
optionalParam["xyz"] = "value"; //Won't fail if the user didn't pass a value
optionalCallback = optionalCallback || function(){};
optionalCallback(); //If I need the function on 20 places, I don't have to insert a typeof-check everywhere
optionalFlag = optionalFlag || false;
}
The advantages are clear and I can deal with both undefined and null parameters.
This will, however, not work for optional flags that default to true:
someFlag = someFlag || true; //Will never evaluate to false.
Return values
Here's another example where I use that syntax:
function getValueOfIndex(idx){
return anArray[idx] || null; //Returns null if the index is out of bounds
}
My Question:
How does the || operator work in my use case?
Can I use || for all of these situations?
Is there any reason not to use it?
Are there any other types or values where this syntax will fail?
Edit: I recognised that my last point (difference between null||undefined and undefined||null) should belong to a seperate question, so I removed it.
The general answer is that you can't use
parameter = parameter || default;
if the user should be able to pass an explicit parameter that's falsey, and that should take precedence over the default. In that case you need to test explicitly for undefined:
parameter = typeof parameter == "undefined" ? default : parameter;
If the user should be able to pass an explicit undefined value and have that take precedence (a very perverse thing to do), you'll need to test arguments.length to determine how many arguments were passed, so you can default only the remainder.
Why do the following two expression return different values?
null || undefined //evaluates to undefined
undefined || null //evaluates to null
something || somethingElse is an expression, meaning it will always return a value, either the first truthy value, otherwise the last value at all. For example false || 17 is 17. Both null and undefined are falsy, so in both cases, || will return the last value.
Can I use || for all of these situations?
|| Can sometimes do something you wouldn't expect
function thisIsUnexpected (a) {
a = a || "other value";
reurn a;
}
thisIsUnexpected(); // will return "other value";
// it can fail when you pass in a falsy value
thisIsUnexpected(false); // you would want it to return false, yet it will return "other value"
To get the correct behavior, you'd want to use a ternary expression as follows. This can never fail.
function thisIsExpected (a) {
a = (a === undefined) ? "other value" : a;
reurn a;
}
The logical OR operator can be used as long as the expression used to test for the presence of an argument returns true for all the cases where an argument is supplied.
someFlag = someFlag || true; //Will never evaluate to false.
Your example above doesn't work because I can supply the argument false and the expression used to test for the presence of an argument (in this case simply someFlag) will still evaluate to false, implying that an argument was not specified.
So you would need to modify the code to something like:
someFlag = (typeof someFlag === 'boolean') ? someFlag : true;
These are the instructions to the script I have to write:
function longest(first, second) {
if (first.length >= second.length) {
return first;
} else {
return second;
}
Use the || operator to specify default values for first and second in
the function. If one or both parameters are not specified, the empty
string should be used as the default value.
Once you make your changes, you should be able to test the function as
follows:
console.log(longest('Alice')); // second is undefined - second defaults to the empty string
//Alice
console.log(longest()); // both first and second are undefined - both default to the empty string
//(an empty string)
console.log(longest('hi','hello'));
//hello
console.log(longest('hi', 'me'));
//hi
console.log(longest(''));
//(an empty string)
I don't even know where to begin. Can someone shed some light for me?
Try this:
function longest(first, second) {
var firstDefault = '';
var secondDefault = '';
first = typeof first !== 'undefined' ? first : firstDefault;
second = typeof second !== 'undefined' ? second : secondDefault;
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
Default value
first = first || '';
Or, but that is not defined in the requirement
first = (typeof first !== 'undefined') ? first : '';
Apply this to both arguments
The issue with
function longest(first, second) {
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
if you call it as longest('Alice') is that it spews out an error:
TypeError: Cannot read property 'length' of undefined
because second is undefined, and properties of undefined like .length can not be read.
undefined is actually a thing in Javascript rather than an automatic error like in many other languages. We'll come back to that soon...
The purpose is to get you to thinking about how to fix the function. If the function assigned a blank string in place of undefined, the blank string would have a length, 0, that could be read.
In Javascript the || operator can be used to assign default values to missing variables as follows:
function longest(first, second) {
var defaultValue = '';
var first = first || defaultValue;
var second = second || defaultValue;
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
Now if either first or second is undefined, they will be replaced locally with the value of the defaultValue variable, which here is set to the empty string ''.
The empty string is not an undefined value, it is a string that contains no characters. It has a length, and that length is zero. Now the if statement will not fail when an undefined value is passed.
Now longest('Alice') yields 'Alice'
Bugs
Unfortunately the assignment as shown does not teach you enough about Javascript. It is probably worth knowing about a peculiar Javascript feature: any property whether it is called 'length' or something else can be read from existing objects that do not have that property. This may lead to undesired behavior. The result is a value called undefined, which is a value that things can be in Javascript.
When undefined is compared with a number, the result is always false. Mathematically that's normally impossible. We normally think that if x>1 is false, then x<1 must be true or x is 1. That kind of logic does not work for undefined.
When undefined is compared with undefined the result is also false, unless it is an equality test which is true.
Why does this matter? It relates to bugs in the longest() function above. Number inputs are one example. Strings representing numbers have a length but numbers do not have a length. Reading the length of a number yields undefined. And comparing undefined with a defined number is false. That means we can do this:
longest(1,100) returns 100 Correct.
but
longest(100,1) returns 1 OOPS.
I'm assigning a javascript variable with a value as
var newline = $("#newline").val();
The $("#newline").val() may or may not exist (in some cases, the #newline may not exist in the DOM, or even if it exists, it may not have any value).
I want to check whether the var newline is set or not. How do I do that?
This comes down to "What does the jQuery val method return if there are no elements matching the selector in the DOM?"
The answer to that is undefined so:
if ( typeof newline === "undefined" ) {
}
jQuery:
(function() {
if (this && this[0] && this[0].value) {
// Has a value
} else {
// Has no value
}
}).call($("#newline"));
this[0] is the HTML Element itself, rather than a jQuery Object.
Pure JavaScript:
(function() {
if (this && this.value) {
// Has a value
} else {
// Has no value
}
}).call(document.getElementById("newline"));