Is there a shorthand way to replace a value with a different value in javascript?
Here's the most concise way I know of yet:
getAttr(data,"PARTITIONING_SCHEME") === "[None]" ? "" : getAttr(data,"PARTITIONING_SCHEME")
But that requires repeating myself, and in this case calling the getAttr function twice to get the same value. Obviously I can assign it to a variable once and then do the conditional logic, but that'd be another line of code and I'm looking for conciseness.
I suppose I could do a string replacement:
getAttr(data,"PARTITIONING_SCHEME").replace("[None]","")
But that would wrongly modify some longer string that happens to have [None] embedded in it. I'm sure regexp could do it but I'd prefer not to have frequent recourse to regexp... just need something quick, concise and easy to remember. Seems simple enough.
This is not asking about the javascript ternary operator ? which is what I showed above and requires repeating the operand on both sides, nor nullish coallescing ?? or || which only replace nullish values. I want to replace one non-nullish value with another, otherwise leave it alone.
I can do this of course by extending the String prototype:
String.prototype.swap = function(o,n) {
return this === o ? n : this
}
And then anywhere in my app:
getAttr(data,"PARTITIONING_SCHEME").swap("[None]","")
But wanted to check to see if there isn't something built-in first?
What about:
getAttr(data,"PARTITIONING_SCHEME").replace(/^\[None\]$/,"")
It will replace [None] only, when it is the only content of the string.
Or create a little utility function:
const noneBlank=s=>s=="[None]"?"":s;
// apply it here:
noneBlank(getAttr(data,"PARTITIONING_SCHEME"))
There is no reference type in javascript, therefore it is not possible to use
attr.someFunc()
or
someFunc(attr)
to assign attr to something else. A variable or attribute binding can only be changed via an assignment.
Surely you can use functions to change the content of the variable, but only when it is mutable. Therefore your imaginary String.swap is not possible either.
A realistic way to solve the problem at hand would be to have setAttr along with getAttr, to which you can pass a mutator function:
setAttr(data,"PARTITIONING_SCHEME", x => x === '[None]' ? '' : x)
Related
I saw the following syntax in JavaScript that allows you to add functions to an Objects element so you can perform a switch alternative. Consider the following:
var insert = insert || {};
insert.Actor = function (user) {
//Do Somthing
}
This would allow you to do the following:
function addUser(type) {
if (insert[type]) {
return insert[type](user);
}
}
I like this implementation but I have two questions:
What exactly is this statement doing and could i just declare a regular object?
var insert = insert || {};
Besides readability what advantages do I get by using this instead of a regular switch statement.
You can add functions to any Object in JavaScript. The syntax you see just "says" If the object already exists... use it, otherwise, create a new object.
var insert = insert || {};
The variable insert is being set to itself, || (OR) being set to {} which is the short syntax for a new Object.
What exactly is this statement doing and could i just declare a regular object?
In JS, foo.bar results in a reference error if foo is not defined. var insert = insert || {}; ensures that insert will be an object, so that checks like if(insert[type]) will work as expected (insert[type] will be undefined)
More generally, || is the logical OR operator, which works as follows: http://www.ecma-international.org/ecma-262/5.1/#sec-11.11 if the left hand side expression (insert in this case) is a "truthy value" (including objects but not values like 0 or undefined), then the value is LHS; otherwise the value is the RHS expression.
Besides readability what advantages do I get by using this instead of a regular switch statement.
You would have to have many conditionals of the form if(insert) in every block of the switch statement. Using this method, you obviate most of them.
insert || {};
Return the first operant that is true from the left to the right.
This is a "OR" operator. In Javascript a "OR" operator dose not simply return true/false boolean value. This is just a short cut to say if insert is not defined, define it as an object.
It really depends on whether you have a reason to believe that insert has already been declared in that scope or not and whether it's the same insert you want or not. Obviously if insert has been defined somewhere else and doesn't do what you want it to do, then this syntax isn't helpful, because it's going to set insert in your scope to the insert that's already defined somewhere else.
Versus using a switch statement, it's a style preference. That's really all it amounts to. You have to ask yourself, "Who will be reading this, and what will be most helpful to them in understanding what this does?"
var insert=insert||{};
is equivalent to:
if (!insert) var insert={};
(if the insert object doesn't exist, create it)
The first expression just makes the code shorter.
This is often used in modular scripts, as any module could initialize the insert object which will then be reused by the other modules.
This question already has answers here:
What are the Alternatives to eval in JavaScript?
(11 answers)
Closed 7 years ago.
I work mainly with javascript, Jquery, knockout, etc
The thing that attracted eval() to me is
var a = 5;
var b = 10;
eval("a+b");
//Gives me output 15
Note: I work in cases where the value of a and b changes dynamically
In my work I'm dealing with a lot of dynamic objects from json, knockout, etc. So eval solves most of my problems.
But as I read I found there are so many issues with eval() like slowing down etc.
I searched a lot and haven't found any substitute for eval() when i have to evaluate equation obtaining as string into equation as object.
Can anyone suggest a plugin or function alternative to eval() keeping in mind the example i have given above
Problem:
I'm creating a Table from Json data using knockout mapping. So that what ever the format of json is the table is generated. I also calculate some field using knockout computed.
Right now I use hard-coded
self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })
self.salaryEqn(salEqnTxt);
I want to execute these equations dynamic. I can create it dynamicaly as string but to eval them is the issue I'm facing.
I want solution for
Is there a way to calculate a formula stored in a string in JavaScript without using eval?
Like a formula
"self.Salary = ko.computed(function(){ return self.salaryEqn() && eval(self.salaryEqn()).toFixed(2); })"
Javascript is a very flexible language in this regard. There are very very few cases where eval() is the right answer to any given question, and it certainly isn't necessary here.
If your a and b variables are part of an object, you can access them with string subscripts:
ie myobj.a could also be referenced as myobj['a'].
From that, you can use a variable for the subscript, and thus you can reference any element in myobj dynamically -- ie:
var myobj = {a : 5, b : 10};
var dynamicProperty1 = 'a';
var dynamicProperty2 = 'b';
//gives 15.
alert( myobj[dynamicProperty1] + myobj[dynamicProperty2] );
No eval() required. You can build the dynamicProperty strings however you wish, so there's virtually infinite flexibility.
If your a and b variables are globals, JS globals in the browser are actually children of the window object, so you can still use this technique even with globals.
ie your global variable a could also be accessed via window.a or window['a'], with the latter option allowing you to do the same dynamicProperty trick described above.
Hope that helps.
do you mean that you want to calculate an equation that you can't know until you've received it?
if so see Calculate string value in javascript, not using eval .
in short:
eval CAN be used sometimes, but only if the equation string comes from a trusted source, and there you need something like evaluating dynamic equations.
maybe using window['var' + num] might be more useful for you. i don't quite understand your question sorry.
If you can collect them under an object like root = {a: 1, b: 2}, then
Object.observe(root, function(newValues) {
res = newValues.object.a + newValues.object.b;
});
can keep your res variable up to date whenever the a or b changes
It looks like you are trying to do dynamic equations created by a user.
For example it could be 'a+b+c' or 'dog+cat', and you don't know.
The best way to handle user-input equations like that is to parse the text into tokens and then translate the tokens into values/operands.
That's a lot of work, but there are pre-rolled solutions. For example, math.js
Check more alternatives to eval in this question and another one here which both might be considered a duplicate...
I understand this is a link only answer, but it will for sure be helpful to others searching for alteratives to eval.
I often find that I write IF statements which immediately reference the value of the conditional statement. For example, let's say I need to check to see if a string matches a pattern:
if (mystring.match(/mypattern/) {
var mymatch = mystring.match(/mypattern/)[1];
...
};
I suspect that what I'm looking for doesn't exist, but I've wondered whether you can reference the conditional statement's value within the if block, the way you can reference "arguments" within a function. In many cases, of course, I can rewrite it like this:
var mymatch = mystring.match(/mypattern/)[1];
if (mymatch) { ... };
But that's often not possible if there's a series of methods called. For example:
var mymatch = $('.myclass')[0].text().match(/mypattern/)[1];
... that would throw an exception if there were no item [0] on which to call .text(). Is there some convenient shorthand I'm missing out on? Or a better way to organize things? Just curious, really — I'll go on living if the answer is no.
In cases where relevant you can use the fact that the assignment operator returns a value in JavaScript, so for instance you can write things like:
if (assignedTest = testedValue) {
//value of assignedTest is now available
//and conditional will only be executed if true
This could be used if the RHS was compatible or properly set-up but it's also a huge readability concern since it's very easy to confuse the assignment = with comparison ==/===.
If you were particularly motivated to pursue this you could extract this type of functionality into a function that would behave in a reliable way: such as assigning the result of a closure to a named variable, and you could further tune the behavior to do other things (such as optionally evaluating to a different value within the test). Ultimately it would primarily be making a simple structure more complex though.
Generally, I test whether or not a variable is set with something like this:
if (variable !== '') {
do something...
}
I know there are other methods for testing variables like typeof but I don't see any advantage - is this an appropriate way to test whether or not a variable is set? Are there problems with it that I should be aware of ?
Two reasons:
1) What if the variable is set by getting the contents of an empty input box?
if(someScenario){
var variable = $('empty-box').val(); }
Perhaps this is only done in certain cases, like when someScenario is true. Later on, you want to check if that variable was set. Your means returns false rather than true. Point is, you can come up with scenarios where you get wrong answers.
There's just no reason not to do it the accepted way.
if(typeof variable !== 'undefined')
It's no slower, has no real flaws, and is only a few characters more.
2) And most importantly, using typeof makes it totally clear what you're asking. Readability is crucial, and if another programmer read the first code, they would think you were checking that it wasn't an empty string. The method using typeof makes it perfectly clear what your conditional is looking for, and reduces the odds of mistakes later on.
If variable has been declared but might not have a value then your code:
if (variable !== '') {
tests if it is not the empty string. Is that what you want? An empty string might be a valid value. Better to test for undefined, or explicitly initialise it to a value that you can then treat as "invalid" (perhaps null, or whatever suits).
If variable has not been declared at all the above code would result in an error such that execution would stop at that point - you can't test the value of a variable that doesn't exist. So if, for example, you're trying to test a global variable that is created inside a function that may not have been called yet, or perhaps you're using several JS files and one needs to test a variable that may or may not have been created by one of the other files, then the only way to do it is with:
if (typeof variable != "undefined") {
Since you're using strict equality testing, the following will all return true:
false
undefined
null
0
The only time your check will return false is when you pass in an empty string.
Is that what you want?
Check out coffeescript's existential operator, by searching "The Existential Operator" on this page: http://coffeescript.org/
The functional problem with your approach is that is that you may inadvertently assign a blank string to variable at some point prior in your script and your logic block will now do the wrong thing.
From a stylistic standpoint your solution is less desirable because your intent to check the existence of the variable is not clear. Someone who was just reading through your code for this the first time might misunderstand what you wrote to mean "I'm expecting there to be a variable named variable set to the blank string" as opposed to "Do something if this variable does not exist."
This might be highly subjective, but my recommendation is to avoid code, that needs to check, whether a variable is set (a.o.t. has some value or type).
Consider this snipplet
var a=false;
if (some_condition) a="Blah";
if (typeof(a)=='string') ....
if (a===false) ...
this makes sure, a is always set, while keeping it easily differentiable from '', null or 0
I'm working on a script that accepts a settings object, but uses default values where settings are not provided.
I just wrote the following line of CoffeeScript:
iframe_width = settings?.iframe?.width? ? $iframe_body.width()
My intent, in plain English, is:
If the settings object is defined, and it defines a property iframe, and the iframe property defines a property width, then assign the value of the latter property to the variable iframe_width. Otherwise, assign the value returned by calling $iframe_body.width().
Does my CoffeeScript code reflect my intent, and is it the most effective way to express that? It seems awkward with all of the existential operators (?), so I wanted to put it out there for some feedback (the compiled JavaScript is very terse and cryptic, so it's hard to tell if should work as intended).
Also, I'm not sure whether there's any redundancy in using both the standard existential operator (?) and its accessor variant (?.) together.
Thanks!
Update:
The code above doesn't seem to work as expected; however, this does:
iframe_width = settings?.iframe?.width ? $iframe_body.width()
That makes sense, since I don't think the former code actually accesses the width property, but rather just checks for its existence (twice, even?). In this code, I removed the ? just after the width property, since I think that's redundant with the ? operator between the two expressions. Does that seem correct?
(Note: This answer was written before the question was updated. As the questioner realized, foo? ? bar isn't just redundant—it actually won't work, because foo? evaluates to true or false, and is therefore always non-null.)
You have two good options for simplifying this: One, you could replace the existential binary operator with an or:
iframe_width = settings?.iframe?.width? or $iframe_body.width()
Two, you could ditch the ? after width—it's redundant:
iframe_width = settings?.iframe?.width ? $iframe_body.width()
Now, you could do both if and only if iframe.width will never be 0 (since 0 or x is x). If you can be sure of that, go ahead and make it
iframe_width = settings?.iframe?.width or $iframe_body.width()