I am currently running JSLint against the javascript in my web application and getting some errors that I require assistance with resolving.
a. First error I am getting is: JS Lint: Unused Variable 'n'.
$.each(collection, function (n, item) {
var temp = item.Id;
// do further processing
});
b. I have all my javascript declared in a self executing function like such:
(function ($, undefined) {
// further javascript code
}
(jQuery));
The above pattern can protect the $ from conflicting with other JavaScript libraries and also protect undefined from being redefined. However I get these errors from it:
JS Lint: Expected an identifier and instead saw 'undefined' (a reserved word).
JS Lint: Unused Variable 'undefined'.
c. JS Lint: Unescaped '-'.
if (value.match(/^[A-Z0-9._%+-]+#(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i)) {
return true;
}
d. JS Lint: Type confusion: 'printer-': string and '(': number.
var frameName = "printer-" + new Date().getTime();
I get numerous errors of Type confusion, sometimes with numbers, integers and other data types. Any idea as to how I can prevent getting these?
e. JS Lint: Insecure '^'.
var value = value.replace(/[^\d\.,\-]/gi, '');
f. JS Lint: Don't make functions within a loop.
for (i = 0, l = txts.length; i < l; i += 1) {
if (/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) {
var func = function () {
//do some processing
};
}
}
A.) See: http://api.jquery.com/jQuery.each/
you can use:
$.each(collection, function() {
doSomething(this); // this refers to the current iteration
});
B.) If you aren't actually using "undefined" you aren't protecting it from anything
C.) I'm not going to bother with regex lol EDIT: Perhaps it wants [A-Z0-9\-]
D.) You are concatenating string with number. Try 'string' + Date.getTime().toString() instead
See also JSLint Type Confusion: function and object with jQuery .css() for type confusion stuff, there are some oddities that I don't agree with
E.) Again I'm not going to try for the regex EDIT: Here's an identical question though: JSLint "insecure ^" in regular expression
F.) If you can create your function once outside of the loop and then use it inside the loop (as long as you do it well) it is a significant performance increase.
I see others have answered, so I'll at least put an attempt in for c)
c. JS Lint: Unescaped '-'.
if (value.match(/^[A-Z0-9._%+-]+#(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i)) {
return true;
}
C. Add a backslash before the - in 9- and +-
Sorry, can't help you with E), that regex looks ok to me.
Related
I was looking through a solution to a problem in javascript, namely parsing a string into its constituent names, operators, and brackets, when I saw this expression:
return accept(")") ? _|_ : e;
What is that _|_? Is that using node's _ feature? I've looked for documentation but not found any.
When I try using it myself, this happens:
> 5
5
> true ? _|_ : 0
ReferenceError: _ is not defined
at eval:1:1
at eval
at n.<anonymous>
As a clarification, the variable _ was not defined anywhere in the code.
This was run on Node v8.1.3, but also works fine on chrome native browser JS.
Here is the code:
function tokenise(string) {
const tokens = string.match( /[a-z]+|\(|\)|[!#$%&*+\-\/<=>#^_.,;]+/gi ) || [];
const accept = s => s===tokens[0] && tokens.shift() ;
const unaccept = s => s!==tokens[0] && tokens.shift() ;
const singles = (e) => ( e = unaccept(")") ) ? [ e, ...brackets() ] : [] ;
const brackets = (e) => accept("(") ? ( e = brackets(), accept(")") || _|_ , [ e, ...brackets() ] ) : singles() ;
try { let e = brackets(); return accept(")") ? _|_ : e ; }
catch(_) { return null; }
}
_|_ has no special meaning in JavaScript, it's just a | (bitwise OR) expression with the identifier _ on both sides of it.
That code checks the result of calling accept and, if it's truthy, returns the result of the | operation; if not it returns the value of e.
Is that using node's _ feature?
_ isn't special in Node code. In the REPL (only), it's a variable that receives the result of the most recently evaluated expression; details here.
As a clarification, the variable _ was not defined anywhere in the code.
That means that if accept(")") returns a truthy value, the code will throw a ReferenceError because _ is an undeclared identifier. If that's what the author intended, there's no need for the | operator at all, but in a now-deleted answer, georg pointed out that they may have used _|_ as an attempt to express the mathematical concept of bottom ("a computation which never completes successfully"), the symbol for which is ⊥. In any case, the author seems to use it to force an exception in an expression context (since throw is a statement; there's talk of possibly allowing it in expression contexts at some point, though).
It take a variable _ and uses a bitwise OR | with itself.
As result, you get a 32 bit integer number.
In addition to what has already been explained here in details, that your code is quite regular JavaScript, with nothing special about it...
I've come across similar code in more than one programming language when the syntax verbosity was used to generate supposedly funny expressions that resemble Text Art, aka ASCII Art, ones that while make the code look weird, are also 100% valid code.
Your code example reminds one of those stupid jokes, just like when someone introduces a function with a paragraph-long name.
very basic JavaScript programmer here!
I was busy on some code with variables that look like this:
blocktype1;
blocktype2;
blocktype3;
blocktype4;
... //everything between blocktype4 and blocktype70, the three dots are not actual code!
blocktype70;
Now I was using eval() in a function where a value was given to one of the blocktype variables. The blocktype depended on the variable "number".
This is what I had for that part:
eval("blocktype" + number) = 3
What I want is, say "number" is 27, then I want the variable blocktype27 to get a value of 3.
When I check the console it says:
ReferenceError: Invalid left-hand side in assignment
Could anyone possibly help me?
I would prefer just vanilla JavaScript and still the use of eval.
Thank you for your time!
The 'correct' solution would probably be to use an Array which is ideal for sequences and are accessible by index.
var number = 1;
var val = 3;
var blocktype = []; // so clean
blocktype[number] = val;
However, properties can be accessed as with the bracket notation as well. This assumes the variables are in global scope and are thus properties of the global (window) object.
var blocktype1; // .. etc
window["blocktype" + number] = val;
The problem with the eval is that is effectively the same as doing f() = 3 which does not make sense: only variables/properties can be assigned to1.
However eval is a built-in function and the results of a function cannot be assigned to, per the error message. It could be written as
var blocktype1; // .. etc (see dandavis' comment)
eval("blocktype" + number + " = " + val);
// What is actually eval'd is:
// eval("blocktype1 = 3")
which quickly exposes a flaw with eval. If val was the string "Hello world!" with would result in eval("blocktype1 = Hello world!") which is clearly invalid.
1 For the gritty: the left-hand side of an assignment has to be a Reference Specification Type, which is a more wordy way of describining the above behavior. (It is not possible for a JavaScript function to return a RST, although it could technically be done for vendor host objects.)
Feel free not to accept this, since it's specifically not using eval(), but:
You can allocate an array of size 71 like so:
var blocktype = new Array(71);
(your number values apparently start at 1, so we'll have to ignore the first element, blocktype[0], and leave room for blocktype[70], the 71st)
You can now assign elements like this:
blocktype[number] = 3;
and use them like so:
alert( blocktype[number] );
I'm trying to alert any JavaScript object as a string, in a function. This means if the parameter given to the function is window.document, the actual object, it should alert "window.document" (without quotes) as a literal string.
The following calls...
example(window);
example(window.document);
example(document.getElementById('something'));
...calling this function...
function example(o) {/* A little help here please? */}
...should output the following strings...
window
window.document
document.getElementById('something')
I've attempted to do this with combinations of toString() and eval() among some more miscellaneous shots in the dark without success.
No need insane backwards compatibility, newer ECMAScript / JavaScript features/functions are fine. Feel free to inquire for clarifications though the goal should be pretty straight forward.
This is not possible to do in a self contained script.
If using a preprocessor would be an option, then you could write one which converts example(whatever) into example('whatever'). Other than that I'm afraid you're out of luck.
The first problem is that objects don't have names.
The second problem is that from your examples, you're not really wanting to print the (nonexistent) name of an object, you want to print the expression that evaluated into a reference to an object. That's what you're trying to do in this example:
example(document.getElementById('something'));
For that to print document.getElementById('something'), JavaScript would have had to keep the actual text of that expression somewhere that it would make available to you. But it doesn't do that. It merely evaluates the parsed and compiled expression without reference to the original text of the expression.
If you were willing to quote the argument to example(), then of course it would be trivial:
example( "document.getElementById('something')" );
Obviously in this case you could either print the string directly, or eval() it to get the result of the expression.
OTOH, if you want to try a real hack, here's a trick you could use in some very limited circumstances:
function example( value ) {
var code = arguments.callee.caller.toString();
var match = code.match( /example\s*\(\s*(.*)\s*\)/ );
console.log( match && match[1] );
}
function test() {
var a = (1);
example( document.getElementById('body') );
var b = (2);
}
test();
This will print what you wanted:
document.getElementById('body')
(The assignments to a and b in the test() function are just there to verify that the regular expression isn't picking up too much code.)
But this will fail if there's more than one call to example() in the calling function, or if that call is split across more than one line. Also, arguments.callee.caller has been deprecated for some time but is still supported by most browsers as long as you're not in strict mode. I suppose this hack could be useful for some kind of debugging purposes though.
Don't know why you need this, but you can try walking the object tree recursively and compare its nodes with your argument:
function objectName(x) {
function search(x, context, path) {
if(x === context)
return path;
if(typeof context != "object" || seen.indexOf(context) >= 0)
return;
seen.push(context);
for(var p in context) {
var q = search(x, context[p], path + "." + p);
if(q)
return q;
}
}
var seen = [];
return search(x, window, "window");
}
Example:
console.log(objectName(document.body))
prints for me
window.document.activeElement
My code looks like this:
$.extend($.fn.dataTableExt.afnSortData, {
'dom-text': function (oSettings, iColumn) {
var aData = [];
$('td:eq(' + iColumn + ') input', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
aData.push(this.value);
});
return aData;
},
'dom-data-rk': function (oSettings, iColumn) {
var aData = [];
$('td:eq(' + iColumn + ')', oSettings.oApi._fnGetTrNodes(oSettings)).each(function () {
aData.push($(this).attr('data-rk'));
});
return aData;
}
});
I used JSLint and it came up with an error:
Warning 21 JS Lint: Unexpected dangling '_' in '_fnGetTrNodes'.
Can someone explain what this means? I don't understand the error message at all :-(
JSLint simply doesn't like identifiers to begin with an underscore character. Change the identifier and the warning will go away, or add the following directive to the top of the file:
/*jslint nomen: true */
The reason it doesn't like them is that people often use it to indicate a "private" variable, but doesn't actually change the behaviour of the variable.
Do not use _ (underbar) as the first character of a name. It is
sometimes used to indicate privacy, but it does not actually provide
privacy. If privacy is important, use the forms that provide private
members. Avoid conventions that demonstrate a lack of competence.
more about code conventions used by JSLint here
You can simply set "tolerate dangling _ in identifiers" to true to ignore this error.
Well, JSlint doesn't like a variable name that begins with an underscore (_).
It is better to use JShint.com instead of JSlint. It's a fork of JSlint and provide you more options of configuration and doesn't show stupid errors like this.
https://stackoverflow.com/a/10763615/1149495
I have a bit of JavaScript code that is specified in a configuration file on the server-side. Since I can't specify a JavaScript function in the configuration language (Lua), I have it as a string. The server returns the string in some JSON and I have the client interpret it using a clean-up function:
parse_fields = function(fields) {
for (var i = 0; i < fields.length; ++i) {
if (fields[i].sortType) {
sort_string = fields[i].sortType;
fields[i].sortType = eval(sort_string);
}
return fields;
}
};
So basically it just evaluates sortType if it exists. The problem is that Firebug is reporting a "Syntax error" on the eval() line. When I run the same steps on the Firebug console, it works with no problems and I can execute the function as I expect. I've tried some different variations: window.eval instead of plain eval, storing the sortType as I've done above, and trying small variations to the string.
A sample value of fields[i].sortType is "function(value) { return Math.abs(value); }". Here's the testing I did in Firebug console:
>>> sort_string
"function(value) { return Math.abs(value); }"
>>> eval(sort_string)
function()
>>> eval(sort_string)(-1)
1
and the error itself in Firebug:
syntax error
[Break on this error] function(value) { return Math.abs(value); }
The last bit that may be relevant is that this is all wrapped in an Ext JS onReady() function, with an Ext.ns namespace change at the top. But I assumed the window.eval would call the global eval, regardless of any possible eval in more specific namespaces.
Any ideas are appreciated.
To do what you want, wrap your string in parentheses:
a = "function(value) { return Math.abs(value);}";
b = eval("("+a+")");
b(-1);
The parentheses are required because they force the thing inside them to be evaluated in an expression context, where it must be a function-expression.
Without the parentheses, it could instead be a function declaration, and it seems as if it is sometimes being parsed that way - this could be the source of the odd/inconsistent behaviour you're describing.
Compare this function declaration:
function foo(arg) {}
with this function-expression:
var funcExpr = function foo(arg) {};
It also has to be a function-expression if it doesn't have a name. Function declarations require names.
So this is not a valid declaration, because it's missing its name:
function (arg) {}
but this is a valid, anonymous function-expression:
var funcExpr = function(arg) {};