this my very first question on stackoverflow, so please forgive me if I am not getting all the etiquette yet.
I am trying to work with a previous script written in JavaScript. There is an if conditional expression in the code that I do not understand. The reason it is confusing to me is because it has 3 arguments. I have never seen an if conditional expression like this in any language, or even in the JavaScript "if" tutorial on http://www.w3schools.com/js/js_if_else.asp. The code snippet I am working with looks like this
if (this.css(alldivs[i], "contentdiv", "check")){ //check for DIVs with class "contentdiv"
setting.contentdivs.push(alldivs[i])
alldivs[i].style.display="none"}
My question is: What does if(foo, bar, "check") mean? Is this an old deprecated string comparison function in JavaScript? Why are there 3 variables in the if conditional expression instead of 2?
What are the advantages of the previous code, compared to something like:
if (this.css(alldivs[i] === "contentdiv")
Thank you for your help.
What does if(foo, bar, "check")
When you have a conditional with comma separated expressions, only the last one matters (the previous ones are also executed, though).
Then, the code is equivalent to:
foo;
bar;
if("check") { /*...*/ }
But you have this:
if (this.css(alldivs[i], "contentdiv", "check"))
That means:
Run this.css(alldivs[i], "contentdiv", "check"), where this is an object which has a the method css (a method is a function which is a property of an object).
Check the returned value.
Maybe you will understand it better this way:
var temp = this.css(alldivs[i], "contentdiv", "check");
if(temp) { /* ... */ }
Let's break down what's happening here. In this line:
if (this.css(alldivs[i], "contentdiv", "check"))
You have two things going on.
You have a function call this.css(alldivs[i], "contentdiv", "check").
You have an if() that checks the return value from that previous function call
This would be equivalent to this expanded code:
var returnVal = this.css(alldivs[i], "contentdiv", "check");
if (returnVal) {
setting.contentdivs.push(alldivs[i]);
alldivs[i].style.display="none";
}
This:
if (this.css(alldivs[i], "contentdiv", "check")) {
Would be equivalent to this:
var temp = this.css(alldivs[i], "contentdiv", "check");
if (temp) {
So you see, it's not an if taking three parameters. It's an if with one parameter which happens to be a function call that takes three arguments.
It's hard to know what answer is going to help you, as your question is about code that doesn't appear in your sample. In this case:
if (this.css(alldivs[i], "contentdiv", "check"))
The condition is based on the return value of the call to this.css. In the sample you seem interested in:
if(foo, bar, "check")
The answer is that it's always going to evaluate as True because of the way the Comma Operator behaves in JavaScript.
Related
Before proceeding, I should mention that yes, I have already read the questions and answers on "Use if statement in React JSX" and its different variants on SO and elsewhere.
However, these posts are more about how to get around without using statements in JSX. I'd like to know why statements aren't allowed in JSX, for which I cannot find any posts on.
I am reading the official documentation on this called "If-Else in JSX", and the reason given for why is, quote,
JSX is just syntactic sugar for function calls and object construction
They go on to contrast the following two pieces of code, the first of which works and the second one doesn't work:
This is valid:
// This JSX:
ReactDOM.render(<div id="msg">Hello World!</div>, mountNode);
// Is transformed to this JS:
ReactDOM.render(React.createElement("div", {id:"msg"}, "Hello World!"), mountNode);
This is not valid:
// This JSX:
<div id={if (condition) { 'msg' }}>Hello World!</div>
// Is transformed to this JS:
React.createElement("div", {id: if (condition) { 'msg' }}, "Hello World!");
I would really like to understand this under the hood. First of all, in the second example, I would never have thought to write JavaScript inside the id property of an HTML element. In fact, this is the first time I've seen code of any sort used in an id property. If I were to try to write an if conditional, I would just do it in curly braces within the render return expression, as a naïve analog of other JS that works (like map or ternary expression).
render() {
return (
{if ...
}
)
I have no doubt that it is perfectly clear to the author of this document that this slightly unorthodox example explains their assertion that "JSX is just syntactic sugar for function calls and object construction", but I cannot figure out how.
Let's start conceptually. What are the definitions of statement vs expression?
A statement does something. An expression evaluates to a value.
JSX is meant to be built up and passed around from one segment of your code to another, eventually ending up as HTML. The name even suggests this "JavaScript to XML" conversion.
The whole point of it is to return a "value" of HTML nodes. JSX kindly allows for expressions, because those help you determine values.
Perhaps it will help to take a closer look at the difference between a ternary expression and an if/else.
If/Else
if(isSaturday){
wakeUpHour = 10;
}else{
wakeUpHour = 7;
}
Ternary
wakeUpHour = isSaturday ? 10 : 7;
Those both accomplish the same thing, right? But under the hood they are operating differently. In English, the if/else might read:
If the value of 'isSaturday' is truthy, run the code inside the curly braces
Assign the number 10 to 'wakeUpHour'
Otherwise, run the code inside the next curly brace
Assign the number 7 to to 'wakeUpHour'
The ternary statement also has two parts:
If isSaturday is truthy, have a value of 10. Otherwise have a value 7.
Assign this value to 'wakeUpHour'
We think of those as accomplishing the same thing. The key point here is that the ternary expression itself is just a value. It's not lines of codes. To do something with that value required another part, assigning it.
In JSX, we don't want to be assigning things. We want values. So we are just taking the ternary expression (a value), not the assignment part or any other code statements.
Finally, and hopefully not to add to your confusion, I would note that you can define functions in JSX.
const myJSX = <button onClick={ () => { return 'hello'; } }>Say hello</button>
Wait, what? I thought we couldn't execute lines of code. It's not executing the lines of code, it's defining them; it's rendered to:
var myJSX = React.createElement("button", {onClick: () => {
return 'hello';
}}, "Say hello");
Compare that with trying to just throw in an if/else statement:
const myJSX = <span>{ if(true){ return 'hello'; } }</span>
Which would try to render as:
var myJSX = React.createElement("span", null, if(true){ return 'hello' });
That doesn't work, for the same reason that you can't normally pass an unencapsulated chunk of code into an argument of a function.
Maybe this is irrelevant to your question, but I've been redirected here because one of my questions said to be duplicate to your question.
if you want to do multi-line JavaScript code, you can wrap your JS code with an IIFE, for example:
<b>
{(() => {
const a = [1, 2, 3].find((el) => el === 2)
// as much code as you want ...
// ...
// ...
console.log(a)
})()}
</b>
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.
Looking through some JS code I have found something like this:
var a, b;
if (
(a = someFunction1(), b = someFunction2() )
){
...
}
I never found anything like this previously and I do not understand the reason for doing something like this. Therefore I am curious: is the person who has done this out of his mind or am I just not capable to understand his idea.
When I try to check what construct like (expression1, expression2) does, I see that it always returns the value of the second expression:
(5, 6) // 6
('strange', 'things') // 'things'
(4, undefined) // undefined
So if I would be the one writing this code, I would do something like this:
var a = someFunction1(),
b = someFunction2();
if (b){ ... }
Am I correct in my reasoning?
When I try to check what construct like (expression1, expression2) does, I see that it always returns the value of the second expression
Yes. Even without trying out, this is what the comma operator does.
Am I correct in my reasoning?
Yes. Your code does exactly the same thing, but is more readable.
You are correct, that is essentially if(b). The readability of the first version is terrible and does not save on space so it would make no sense for it to be minified like that.
Assigning variables inside of conditional statements is bad practice.
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;
}
'onhashchange'in(window)
Having in() work is not a surprise, as new(XMLHTTPRequest) or typeof(x) are other examples of this construct, but not having to separate the string and in is.
Is this per ECMAScript specs? It works in Chrome and FF, haven't tested IE.
From what I can tell, there's no difference whether you wrap window in parenthesis or not in this particular instance. Either way, it checks for this member on the window object.
Might be less confusing if you use spaces:
'onhashchange' in (window)
The same as
'onhashchange' in window
in is not a function, but when you remove the spaces I can see how you read it as such. One advantage to wrapping window in parenthesis is that you can then minify the code:
'onhashchange'in(window)
Something you could not do without the parenthesis.
' is a token that ends a string, so a pair of '' are semantically unambiguous, you don't need whitespace after the end of a string for the lexer to know that it has reached the end of a string.
Another way of saying that is that this works for the same reason that 'Hello '+'world' works.
Additionally, in is a keyword, not a function. It seems like you're thinking of () as the "function call operator", but in this case it's just a disambiguating parentheses.
It's like asking "why does 1 +(2) work?" + doesn't become a function just because you follow it with a paren, and similarly the following will work:
function foo(){}
foo
();
Javascript is brittle with its whitespace rules.
I'm not sure if the notation is confusing you (that maybe in() is a method?), but in is one of those elements of JS that few people correctly understand (I didn't really understand it until quite recently). This is a simplified version showing what in does:
var foo = {
'bar':1,
'barbar':2
}
console.log('bar' in foo); //true
console.log('baz' in foo); //false
What makes this all the more confusing is that you can use in inside a for() loop, as if it (in) were an iterator. The way I tend to think of for loops is like this:
for (exp1; condition; exp2) {
/* statements */
}
for (condition) {
/* statements */
}
In other words, the loop will continue until the in condition fails, which will happen when it runs out of members.