I know that jslint/jshint don't like it but I wanted to know if there were any real issues with doing something like.
var err = function(msg) { throw new Error(msg); };
Example 1: Assignment
var foo = bar.foo || baz.foo || err('missing foo property');
Example 2: Validation
typeof foo['bar'] !== 'string' && err('bar has to be a string');
Are there any gotcha's that I should be aware of?
I know that jslint/jshint don't like it but I wanted to know if there were any real issues with doing something like.
var err = function(msg) { throw new Error(msg); };
Example 1: Assignment
var foo = bar.foo || baz.foo || err('missing foo property');
Example 2: Validation
typeof foo['bar'] !== 'string' && err('bar has to be a string');
Are there any gotcha's that I should be aware of?
Share Improve this question asked Nov 1, 2012 at 16:45 Ilia CholyIlia Choly 18.6k14 gold badges94 silver badges164 bronze badges 19-
2
Example 1 certainly looks dangerous since if
bar.foo
orbaz.foo
exist but are not truthy then it will very quickly get very muddy – Matt Whipple Commented Nov 1, 2012 at 16:51 -
@MattWhipple Good point! So maybe it should be
var foo = "foo" in bar || "foo" in baz || err('missing foo property');
? – Ian Commented Nov 1, 2012 at 17:07 - @Ian It's probably best avoided if it can't be done cleanly (once the point where the short cut isn't quite so short). Your solution is beginning the descent towards obfuscatory idioms. – Matt Whipple Commented Nov 1, 2012 at 17:10
- @iliacholy If you like that solution then you likely should not be considered with what jslint tells you at all – Matt Whipple Commented Nov 1, 2012 at 17:11
-
@MattWhipple So what do you mean? Instead of using this short circuiting, just make it more organized with
if / else
? – Ian Commented Nov 1, 2012 at 17:12
5 Answers
Reset to default 3As far as I'm aware, this is no more wrong than or die()
in PHP. The short-circuit-ness of the operator is clearly-defined, so the error will only be thrown if the last case is reached.
As covered in the ments there is a strong chance of unexpected behavior due to JavaScript's loose interpretation of truthiness which is the driving force of the mentioned logical operators. As such there is a limited subset of conditionals in which the short circuit approach will be useful, and it therefore does not offer a consistent solution.
Out of the 2 examples given example 2 is a good application as it is a readable application of a test with very defined output. Example 1 however will cause issues if any of the attempted values evaluate to anything which may be valid in the program logic, but false
from the perspective of the language. Applying a solution to these types of problems would effectively cancel out any benefit that the syntax could offer. Solutions for variations on these types of issues may not be consistent, and therefore this introduces a higher risk of bugs introduced at initial creation or any subsequent modifications.
One of important things to consider is the precedence and interaction with some other operators. Incorrectly placed ,
or brackets can change flow in subtle and not-so-easily readable way. Otherwise it should be safe as long as you ensured that you intended logic matches shortcut rules. And of course, usual gotchas to what language consider truthly apply as well.
Short circuiting the way you've shown in the question should be absolutely fine and imo preferred over elaborate if-else statements (of course the main condition you are checking should be correct in the first place, but that's not the topic here). In addition to more elegant looking code, you are essentially shaving bytes off of the total data the client has to download which is always good.
Well, if you are particularly checking if the type is string
, you are missing a big point. The raw type string has no methods.
var s = 'something';
console.log(typeof s);// outputs string
var s = new String('something');// same text as above
console.log(typeof s);//outputs object
JavaScript has a feature called auto-boxing. when you invoke string methods on variables declared in the first way, it will automatically switch from string to object string so the proper way to check for a string is:
isString = function (obj) { return toString.call(obj) === '[object String]';};
Triple equal(===) is used to quickly avoid undefined/null cases and mon parison pitfalls.
Other than that, you are fine. In production, you should also log your errors accordingly and use try catch blocks when you invoke throw functions.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744268468a4565980.html
评论列表(0条)