I saw a code fragment like this:
with(document)0[(getElementsByTagName('head')[0] || body).appendChild(createElement(xxx))]
I don't know how to understand with(document)0[]
This is not valid JavaScript syntax and, trying to read around that, the semantics are extremely unclear.
I imagine the author meant something like this:
document.getElementsByTagName('head')[0] || document.body.appendChild(createElement(xxx))
"If there are any <head> tag in the document, return the first. Otherwise return the the result of appending createElement(xxx) to the body".
It is hard to answer this question without the full code. But I'll made some assumptions here.
The first thing that I'd like to say is to avoid of using with() statement. It is not recommended in ECMAScript 5 and is forbidden in strict mode. And one of the reasons is your fragment - this code confused a lot of people, even you.
So let's rewrite it a little bit to make it more understandable:
with(document) {
0[(getElementsByTagName('head')[0] || body).appendChild(createElement(xxx))];
}
How with works you can read here - with statement, but basically it is give us an ability to use directly all the properties and methods of the expression that we are sending to with (in our case it's a document).
So, how this code fragment will looks like without with?
0[(document.getElementsByTagName('head')[0] || document.body).appendChild(document.createElement(xxx))];
The only answer that I don't have is - why to execute this code inside of brackets? The assumption that I have is the following:
this code fragment (document.getElementsByTagName('head')[0] || document.body).appendChild(document.createElement(xxx)) will return the node of new created element. But if we place this code into the 0[], it will return undefined as there is no such property. Again, it's hard to understand all parts of this code fragment without the whole picture.
Related
I can usually Google and find my answer, but I have no idea with this issue on where to even start. If someone could point me in the right direction here as to what language and syntax is being used here, I'd appreciate it.
This is saying "if input1 = 'option1', then output text1 into span1 and if not, input text2.
I'm sorry this is so basic, but need to learn how to edit this but I'm lost without a tutorial or guide.
$('#span1').html(input1='option1'?'text1':'text2');
This is kind of a repost from an earlier question I had where I was accused of trying to get free coding advice so I've made this as basic as possible. I'm not looking for free coding here - if someone could give me a hint as to where I could find more information, I'd appreciate it.
This is a snippet of jQuery - a javascript framework.
$('#span1').html(input1='option1'?'text1':'text2');
$ This is the jQuery "object", and passing a selector argument to it will return a jQuery-wrapped object that you can chain methods to.
#span1 selector argument (may as well be CSS)
input1='option1'?'text1':'text2' Will output "text1" or "text2" depending on wether or not the variable option1 evaluates to true. It's very likely, as u_mulder points out, that this is going to fail. Use two == or three === for comparisons!
html(...) The html method chained onto the output of the selector accepts the new value to write to that element's contents in the DOM.
Suggested reading:
What is a jQuery Object?
Which equals operator (== vs ===) should be used in JavaScript comparisons?
http://api.jquery.com/html/
https://api.jquery.com/category/selectors/
Was able to do it not using that code but a code I'm more familiar with like this:
if(pay_type == 'onetime') {
$('#bank_card_pay_type').html('one time payment');
}
else if(pay_type == 'montly') {
$('#bank_card_pay_type').html('3 monthly payments');
}
else if(pay_type == 'monthly12') {
$('#bank_card_pay_type').html('12 monthly payments');
}
I'm making a library, and I often inspect the result of Closure Compiler's output to see how it's doing things (I do have unit tests, but I still like to see the compiled code for hints of how it could compress better).
So, I found this very weird piece of code, which I never seen before.
variable : {
some();
code()
}
Note: this is not an object literal! Also, there is no ? anywhere that would make it a ?: conditional.
That code is in a regular function block (an IIFE).
variable, in this case, is an undefined variable. There's no code making it true, false, or whatever, and just to make sure, I put a console.log in there and indeed, I get a ReferenceError.
Please do note that I test my code in IE8 too, so this isn't just in modern browsers. It seems to be standard, plain old javascript.
So let's experiment with it. Firing up Chrome's console, I get this:
undeclaredVariable:{console.log('does this get logged?')} // yes it does.
trueValue:{console.log('what about this?')} // same thing.
falseValue:{console.log('and this?')} // same thing.
but then...
(true):{console.log('does this work too?')} // SyntaxError: Unexpected token :
...and...
so?{console.log('is this a conditional?')}:{alert(123)} // Unexpected token .
So what does it do?
thisThing:{console.log('is used to declare a variable?')}
thisThing // ReferenceError: thisThing is not defined
Please, I'd love it if someone could explain to me what this code is meant to do, or at least what it does.
It is a label
Provides a statement with an identifier that you can refer to using a
break or continue statement.
For example, you can use a label to identify a loop, and then use the
break or continue statements to indicate whether a program should
interrupt the loop or continue its execution.
Another common place you see it is when people stick the wonderful and useless javascript: on event handlers.
This is a label (the bit ending with a colon) followed by a block (the code surrounded by the curly brackets).
Blocks usually follow control statements, like if(...) { /*block*/ }, but they can also simply stand on their own, as in your example.
Labels allow jumping up several loops at a time with a continue or break; see the linked MDN page for several examples, such as:
var itemsPassed = 0;
var i, j;
top:
for (i = 0; i < items.length; i++){
for (j = 0; j < tests.length; j++)
if (!tests[j].pass(items[i]))
continue top;
itemsPassed++;
}
Here, top: is a label that code inside the inner loop can jump to, in order to escape to the outer loop.
For the sake of anyone who doesn't know what JSON is, and sees a colon in what might actually be an object, and is trying to figure out what it is, and finds this discussion, a colon is also used in JSON. There is a practice of embedding functions in a JSON object. Which might be confusing (As it was to me) for anyone who happens to see this for the first time. (Everyone isn't born with the knowledge of JSON and JavaScript programmed into their brains.) So if you find yourself at this discussion, and you think that every time you see a colon in JavaScript, that it's a label, it might not be. It might be that it's a colon after a label, OR it might be part of JSON. In fact, a colon in JSON being shown as a string, is a lot more common than a label. JSON in the form of an object, will be displayed as [object Object], with all the content hidden. So, unless the JSON is in the form of a string, and you display an object to the console (console.log(object)) all you will see is [object Object]. It is common practice to write JavaScript code, wrapped in an object. In that case you will see the JSON in the form of code. That's when you'll ask yourself, "What is this? and what is that colon for?" Then you'll find yourself at this discussion, and be told that it's a label, when it's really part of JSON. The topic of this discussion is worded: "Please explain this usage of a colon in javascript", and then the "correct answer" is marked as having to do with a label. The correct answer is that a colon can be used in more than one way. So, if you don't know what JSON is, or think you know (like I did, but didn't really understand) read about it here:
JSON.org
That is just a label.
you can use continue [label name] (or break) in a loop to go to a label.
More explanations of what they are can be seen throughout the interwebs.
it is used for labeling an statement in jsvascript.check more detail here.
the labeled statement can be used with break and continue later.
I am have some JavaScript functions that run on both the client (browser) and the server (within a Java Rhino context). These are small functions - basically little validators that are well defined and don't rely upon globals or closures - self-contained and portable.
Here's an example:
function validPhoneFormat(fullObject, value, params, property) {
var phonePattern = /^\+?([0-9\- \(\)])*$/;
if (value && value.length && !phonePattern.test(value))
return [ {"policyRequirement": "VALID_PHONE_FORMAT"}];
else
return [];
}
To keep things DRY, my server code gets a handle on each of these functions and calls toString() on them, returning them to the browser as part of a JSON object. Something like this:
{ "name" : "phoneNumber",
"policies" : [
{ "policyFunction" : "\nfunction validPhoneFormat(fullObject, value, params, property) {\n var phonePattern = /^\\+?([0-9\\- \\(\\)])*$/;\n if (value && value.length && !phonePattern.test(value)) {\n return [{\"policyRequirement\":\"VALID_PHONE_FORMAT\"}];\n } else {\n return [];\n }\n}\n"
}
]
}
My browser JS code then takes this response and creates an instance of this function in that context, like so:
eval("var policyFunction = " + this.policies[j].policyFunction);
policyFailures = policyFunction.call(this, form2js(this.input.closest("form")[0]), this.input.val(), params, this.property.name));
This all works very well. However, I then run this code through JSLint, and I get back this message:
[ERROR] ValidatorsManager.js:142:37:eval is evil.
I appreciate that often, eval can be dangerous. However, I have no idea how else I could implement such a mechanism without using it. Is there any way I can do this and also pass through the JSLint validator?
I wouldn't worry about it since you are only passing these function strings from the server to the client, and are thus in control of what will be evaluated.
On the other hand, if you were going the other direction and doing the evals of client-passed code on the server, that would be an entirely different story...
Update:
As disabling the validation option in your comment may cause you to miss future errors, I would instead suggest passing the function name rather than the entire function and have the function library mirrored on the server and client. Thus, to call the function, you'd use the following code:
var policyFunction = YourLibraryName[this.policies[j].policyFunctionName];
var policyArguments = this.policies[j].policyArguments;
policyFunction.apply(this, policyArguments);
Update 2:
I was able to validate the following code with JSLint successfully, which essentially allows you to "turn off" validation for the vast minority of cases where eval is appropriate. At the same time, JSLint still validates normal eval calls, and all uses of this method should throw up flags for future developers to avoid using it/refactor it out where possible/as time allows.
var EVAL_IS_BAD__AVOID_THIS = eval;
EVAL_IS_BAD__AVOID_THIS(<yourString>);
Dont encode a function as a string in JSON. JSON is for content, which you are confounding with behavior.
Instead, I suppose you could return JS files instead, which allow real functions:
{ name : "phoneNumber",
policies : [
{ policyFunction : function() {
whateverYouNeed('here');
}
}
]
}
But while that solves the technical issue, it's still not a great idea.
The real solution here is to move your logic out of your content entirely. Import a JS file full of little validation functions and call them as needed based on a dataType property in your JSON or something. If this functions are as small and portable as you say, this should be trivial to accomplish.
Getting your data all tangled up with your code usually leads to pain. You should statically include your JS, then dynamically request/import/query for your JSON data to run through your statically included code.
I would avoid using eval in all situations. There's no reason you can't code around it. Instead of sending code to the client, just keep it hosted on the server in one contained script file.
If that's not doable, you can also have a dynamically generated javascript file then pass in the necessary parameters via the response, and then dynamically load the script on the client side. There's really no reason to use eval.
Hope that helps.
You can use
setInterval("code to be evaluated", 0);
Internally, if you pass setInterval a string it performs a function similar to eval().
However, I wouldn't worry about it. If you KNOW eval() is evil, and take appropriate precautions, it's not really a problem. Eval is similar to GoTo; you just have to be careful and aware of what you're doing to use them properly.
With very little parsing you could have had it like so:
var body = this.policies[j].policyFunction.substr;
body = body.substr(body.indexOf("(") + 1);
var arglist = body.substr(1, body.indexOf(")"));
body = body.substr(arglist.length + 1);
var policyFunction = new Function(arglist, body);
Which would provide a bit of validation, avoid the literal use of eval and work synchronously with the code. But it is surely eval in disguise, and it is prone to XSS attack. If the malevolent person can get their code loaded and evaluated this way - it will not save you. So, really, just don't do it. Add a <script> tag with the proper URL and that would be certainly safer. Well, you know, better safe then sorry.
PS. My apologises if the code above doesn't work, it only shows the intent, I've not tested it, and if I made a mistake at counting parenthesis or some such - well, you should get the idea, I'm not advertising it by any means.
DRY is definitely something I agree with, however there is a point where copy+pasting is more efficient and easy to maintain than referencing the same piece of code.
The code you're saving yourself from writing seems to be equivalent to a clean interface, and simple boiler plate. If the same code is being used on both the server and the client, you could simply pass around the common pieces of the function, rather than the whole function.
Payload:
{
"name": "phoneNumber",
"type": "regexCheck",
"checkData": "/^\\+?([0-9\\- \\(\\)])*$/"
}
if(payload.type === "regexCheck"){
const result = validPhoneFormat(fullObject, value, payload.checkData)
}
function validPhoneFormat(fullObject, value, regexPattern) {
if (value && value.length && !regexPattern.test(value))
return [ {"policyRequirement": "VALID_PHONE_FORMAT"}];
else
return [];
}
This would give you the ability to update the regex from a single location. If the interface changes it does need to be updated in 2 places, but I wouldn't consider that a bad thing. If the client is running code, why hide the structure?
If you really, really want to keep both the object structure and the patterns in one place - extract it to a single API. Have a "ValidatePhoneViaRegex" api endpoint which is called by all places you'd be passing this serialized function to.
If all of this seems like too much effort, set jslint to ignore your piece of code:
"In JSHint 1.0.0 and above you have the ability to ignore any warning with a special option syntax. The identifier of this warning is W061. This means you can tell JSHint to not issue this warning with the /*jshint -W061 */ directive.
In ESLint the rule that generates this warning is named no-eval. You can disable it by setting it to 0, or enable it by setting it to 1."
https://github.com/jamesallardice/jslint-error-explanations/blob/master/message-articles/eval.md
I would prefer to see copy+pasted code, a common api, or receiving parameters and copy+pasted boiler plate than magical functions passed in from the server to be executed.
What happens if you get a cross-browser compatibility error with one of these shared functions?
Well, the first thing to bear in mind is that jsLint does make the point that "it will hurt your feelings". It's designed to point out where you're not following best practices -- but code that isn't perfect can still work just fine; there's no compulsion upon you to follow jsLint's advice.
Having said that, eval is evil, and in virtually all cases there is always a way around using it.
In this case, you could use a library such as require.js, yepnope.js or some other library that is designed to load a script separately. This would allow you to include the javascript functions you need dynamically but without having to eval() them.
There are probably several other solutions as well, but that was the first one that came to my mind.
Hope that helps.
I would like to know if leaving an empty if statement for certain situations as:
else if(typeof console === 'undefined'){}
Just to have the code bypass the rest of the function It is an accepted and safe way to work or there are other recommendation practices for these cases?. Thank you.
It's fine and safe to leave if branches empty, the only thing I would add is a comment:
else if(typeof console === 'undefined')
{
//explanation why nothing has to go here
}
Without seeing the rest of the code I'm unsure how you're using this to "bypass the rest of the function", there may be a better way to do this.
From what information you've provided me, I can glean that the answer is "no". It will work, but it's bad style. If you would like to bypass the rest of the function, why not return; or put most of the logic in the if statement that pertains to it so that there is no bypassing at all?
I just had a case in which I chose to use an empty if-statement (professional context). I must agree though, there definitely is a technically cleaner solution. Still, since in a professional context time is important too, I chose to use the empty if-statement in my case, so I wanted to share my train of thought with you.
In my case I'm patching existing code with a variable that is used to skip already existing nested if-statements. The main function keeps running before and after the statement.
Original Code:
if(bValidateA){
}elseif(bValidateB){
}elseif(bValidateC){
}
// ... code continues with variables set inside the statements.
Now we want to add a global Parameter to not validate anything. What are my options and why do they suck?
Solution A sucks because much work and less easy to read:
if(!bValidateNothing && bValidateA){
}elseif(!bValidateNothing && bValidateB){
}elseif(!bValidateNothing && bValidateC){
}
Solution B sucks because empty if-statement:
if(bValidateNothing){
// empty
}elseif(bValidateA){
}elseif(bValidateB){
}elseif(bValidateC){
}
Solution C sucks because it becomes too nested (in my case there have been some additional ifs in the original code):
if(!bValidateNothing){
if(bValidateA){
if(xx){
}elseif(xy){}
}elseif(bValidateB){
}elseif(bValidateC){
}
}
Solution D, the technically cleanest solution by adding additional functions, sucks because you need to split your code, which needs a lot of time, and may result in new errors.
(no pseudocode)
So, to answer the question "accepted and safe": it works, it's readable, safe and quick. Sometimes that has to be enough, considering the alternatives. If you have the time to avoid using it, I'd probably still recommend that instead.
Funny enough, the time I saved by using this quick way to implement my logic, has now been successfully spent adding my cents to this ten year old already answered question.
Just don't write a block for a case you don't want to handle.
If you only want to do something when console exists, then do that:
if(typeof console !== 'undefined'){
// your code
}
// else if(typeof console === 'undefined'){}
// you don't need that second part
Or maybe I didn't quite get your issue?
Same as Pioul's answer, but I'd add that imo checking existence in javascript looks much tidier with the !! (notnot) operator.
if(!!console){
// your code
}
// else if(!console){}
// you don't need that second part
Sometimes it is useful to have debugging information printed out:-
if(typeof console !== 'undefined'){
console.log("debug info");
}
Then, before releasing the code, simply comment out all the console.log's
// console.log("debug info");
This can be done with a macro.
It will leave an empty if statement. But this is not a compilation error so that's OK.
Note, that if you're going to comment out the line it is important that braces are used. Otherwise you'd have the next line dependent on the if statement which would be a bleeding shame.
Using an empty if statement can be a valid and accepted practice in certain situations.
For example, when working with a try-catch block, you may use an empty if statement to handle specific errors without disrupting the rest of the function. Additionally, it can be used for performance optimization by short-circuiting the evaluation of certain conditions.
Make sure that when using an empty if statement, it is properly commented to provide context and explanation for its use.
Example:
try {
// code that may throw an error
} catch (error) {
if(error instanceof SpecificError) {
// handle specific error without disrupting the rest of the function
}
}
Another example:
if(isFirstConditionTrue && isSecondConditionTrue && isThirdConditionTrue) {
// Do something
} else if(isFirstConditionTrue && isSecondConditionTrue) {
// Do nothing, because third condition is false
} else {
// handle other conditions
}
It's always a good practice to add comments explaining the purpose of each empty if statement and why you chose to use it in a certain scenario. It's not generally considered bad style as long as it serves a specific purpose and is well documented.
I'm doing some research for a project that I have going on the uses the document.createTreeWalker and I'm looking at a script that uses quite a few xpath's, but I'm curious as to where these come from. Some are obvious and I have been able to find answers to online, such as [#AttributeName] and [#TagName], but what is [#StoreName], [#AttributeValue1], [#AttributeValue2]...these I have not been able to look up online.
Particularly, I'm looking at these lines and not understanding:
thisURL = window.document.location.href.toString();
if(thisURL.search("[#StoreName]") != -1) { //do something }
Perhaps I'm misunderstanding your question, but there's nothing functionally or syntactically different between [#AttributeName] and [#StoreName]. They're both predicates that are looking for elements with particular attributes. The first one is looking for AttributeName attributes, while the second is looking for StoreName attributes.
That said, the code you're showing isn't actually doing any XPath work. It's just looking at whether the URL contains the character sequence [#StoreName] using JavaScript's string search function, and doing something if it does.