space and/or perfomance wise, what would be a more efficient way to add strings, in the case of having many string literals concatenated together, in Javascript?
x += y;
OR
x + y;
I've been pondering about this for a while. Of course for a case where there are only two strings being concatenated together there would be virtually no difference, but what about cases where a CSS or html document is being structured inside the JS, or a huge XML, for whatever reason?
string += " classA {}";
...
.....
string += "classX {}";
VS
string + "classA {}" +
...
.....
+ "classX {}";
Sorry if this sounds like a basic question, but I had a similar problem when I had to code an XML parser in Java and realized the usage of StringBuilder. Not sure how this translates to JavaSript.
Do you want to modify x? More specifically, does it matter if x gets modified?
x + y on its own doesn't do anything unless used as an argument or captured to a variable. let z = x + y does, as does f(x + y).
x += y is equivalent to x = x + y and so modifies x, which may or may not be what you want.
Normally if your intent is to "append to x" and save the result then you'd say x += y.
If your intent is to use the combined x and y in some other place, such as f(x + y), then that's appropriate. Here f(x += y) sends mixed messages, as it's not clear why you'd be appending and calling.
It's purely your own choice. How you're comfortable doing. Doesn't have any specific standard to it. I could argue that when using x += y when you have to use multiple statements between the string declaration & modification. However, again it still comes down to your own choice.
Related
Today I've had to take a break from debugging my code to debug my debug messages. Consider:
let x = 1;
console.log('x is ' + x + ' and x-1 is ' + x-1);
// ^^^
// 'NaN'
I get why this happens: by the time we get to the subtraction, x is already a string, and it makes no sense to subtract an integer from a string. (But if x gets multiplied by 2 instead, the result is the intuitively correct 2; and when you add an 1 to x, you get 11, also understood).
The question is, is there a way to avoid or work around this behavior, since there is no sprintf() equivalent in JavaScript? In my case x was a loop index and an array index and it took me a moment to catch why my console.log statements were showing nonsense.
I have created a Chrome extension that can draw the graph of the math equation user has inputted. To get the value of y easily, I used eval() (Yes I know it is bad) because the easiest way to achieve it.
var equ = $("#equ1").val(); //some element
//let's say equ = "2(2^x) + 3x"
//some magic code
//equ becomes "2*(pow(2,x))+3*x"
for(var x = -10; x < 10; x++){
var y = eval(equ.replace(/x/ig, x)); //calculate y value
drawPoint(x, y);
}
console.log("Graphing done.");
However, because of the new manifest version 2, I can't use eval anymore. I can't think of any way to manipulate the string. Any idea?
The clean way: You could try parsing the expression using Jison and building an AST from the input string. Then, associate functions with the AST node that apply the operations that the nodes represent to data given to them. This would mean that you have to explicitly put every math expression that you want to support in your grammar and your node code, but on the other hand, this would also make it easier to support mathematical operators that JS doesn't support. If you're willing to invest some time, this probably is the way to go.
The dirty way: If your extension is used on normal websites, you might be able to do some kind of indirect eval by injecting a <script> element into the website or so – however, that would likely be insecure.
Did you try New Function() ... ??
var some_logic = "2*(Math.pow(2,x))+3*x";
args = ['x', 'return (' + some_logic + ');'];
myFunc = Function.apply(null, args);
for (var x = -10; x < 10; x++) {
var y = myFunc(x);
console.log(x, y);
}
console.log("Graphing done.");
Fiddle - http://jsfiddle.net/atif089/sVPAH/
I'm using SlickGrid and the related DataView's groupBy functionality. I would like to group by a pair of columns, but groupBy only allows grouping by a single value.
To get around that (in the AFAICT supported and intended way), I want to pass DataView a function h(row) {return TUPLE(row.x, row.y)}, where TUPLE corresponds to the f in this question's title: it should return an object which behaves with respect to equality as if it was a two-tuple of TUPLE's first and second argument: [Then DataView would group the rows by h(row)]
My best solution is something like
x.toString().replace("," by "") + "," + y.toString().replace("," by "")
More generally:
Choose a separator string S (e.g. ,)
Convert each argument to a string
Remove all occurrences of S from each such string
Insert S between all the strings (a la return theStrings.join(S))
My only complaint against this solution is that it feels incredibly icky. That, however, is sufficient to come here and ask if I'm missing some kind of language idiom, best practice or design pattern.
You can use a pairing function if both the two arguments are numbers(or can be converted to numbers).
f(x, y) = (x + y) * (x + y + 1) / 2 + y
See more: http://en.wikipedia.org/wiki/Pairing_function
I'm taking some information from some variables I have already defined outside this function to create a html svg text box.
Here is the function which is causing me trouble:
RenderTextBox:function()
{
alert('this.x: ' + this.x);
alert('this.y: ' + this.y);
this.textBox = paper.text(this.x, this.y, this.htmlTextBox);
}
The alerts works prefectly, and prompt me with the values expected. However, the final line which is supposed to create the text box puts them nowhere to be seen. Does anybody know why?
If I replace 'this.x, this.y..' with numerical values in the final line of the function, the text box is placed correctly. It's only when I use the 'this.x' and 'this.y' that I have issues.
Sometimes numerical values are converted in strings. That's one of the very bad point about javascript : variables are not needed to be typed.
You should try to parse them as int in order to make them react as integers again : http://www.w3schools.com/jsref/jsref_parseInt.asp
Wild Guess: an you try putting this.x and this.y into variables and then passing these variables to the function call in the last line?
Something like:
var tx = this.x;
var ty = this.y;
this.textBox = paper.text(tx, ty, this.htmlTextBox);
I'm studying for an exam on JavaScript at the moment. I've also got a little knowledge of C and Perl so I'm familiar with prefix and postfix operators in all three languages.
I did an online practice exam for it and one mistake I made was in evaluating the following code:
var x = 10;
x += x--;
Now, I thought it would evaluate to 19 because it would be 10 + 10, then subtract 1 to make 9. But the feedback I got was that it was wrong and it actually evaluates to 20. I thought that sounded a bit suspicious so I tested it out in an HTML document, and it came out with 20 again. I then tried the equivalents in C and Perl and both evaluated to 19.
Can anyone explain to me why JavaScript evaluates the answer as 20 when other languages evaluate it to 19? The answer I got from the test wasn't too clear to me:
The increment ++
and decrement -- operators can be placed
either before or after an operand. If the increment or decrement
operator is placed before the operand, the operation occurs immediately.
If the increment or decrement operator is placed after the operand, the
change in the operand's value is not apparent until the next time the
operand is accessed in the program. Thus the expression x += x-- is equivalent to x = x +
10 which evaluates to 20.
Expanding the statement
x += x--;
to the more verbose JS code
x = x + (function(){ var tmp = x; x = x - 1; return tmp; })();
the result makes perfect sense, as it will evaluate to
x = 10 + (function(){ var tmp = 10; x = 10 - 1; return tmp; })();
which is 20. Keep in mind that JS evaluates expressions left-to-right, including compound assignments, ie the value of x is cached before executing x--.
You could also think of it this way: Assuming left-to-right evaluation order, JS parses the assignment as
x := x + x--
whereas Perl will use
x := x-- + x
I don't see any convincing arguments for or against either choice, so it's just bad luck that different languages behave differently.
In C/C++, every variable can only be changed once in every statement (I think the exact terminology is: only once between two code points, but I'm not sure).
If you write
x += x--;
you are changing the value of x twice:
you are decrementing x using the postfix -- operator
you are setting the value of x using the assignment
Although you can write this and the compiler won't complain about it (not sure, you may want to check the different warning levels), the outcome is undefined and can be different in every compiler.
Basically, the value of x is decemented after assignment. This example might make it clearer (run in Firebug console)
var x = y =10;
x += y--;
console.log(x , y); // outputs 20 9
In C, the line
x += x--;
is undefined behaviour. It seems like your particular compiler is treating it like:
oldx = x--;
x = x + oldx
However, the ECMAScript specification does specify op= - and it gets the value of the left-hand-side before evaluating the right-hand-side.
So it would be equivalent to:
oldx = x--;
x = oldx + oldx