Tag Archives: Function

JavaScript Snippet – isValidVarName()

Now Available in YourJS

Recently I was working on a function which needed to determine whether or not a string could be used as a variable name. Variable name validation can get tricky so instead of using a crazy regular expression which includes all keywords (which may change over time) and instead of testing for strange unicode characters which are rarely used for variable names, I decided to leverage the JavaScript Function constructor:

The above function takes the string in question and returns true if the string can be used a variable name. If the string can not be used as a variable name false is returned.

Some may wonder why I’m doing the following:

varName.replace(/[\s\xA0,\/]|^$/g, '.')

The reason I included the above replacement is to avoid false-positives in the case of an empty string, extra spacing, commas, and forward slashes.

Security

Others have attempted to make the same function using the evil eval() function which allows for JS injection. Even though the Function constructor can also be used for evil, when supplying arguments it does prevent you from doing JS injection by making sure the arguments don’t have parentheses.

Examples

The following is an example of what will happen when running for the function for a number of strings:

console.log(isValidVarName(''));           // -> false
console.log(isValidVarName('3'));           // -> false
console.log(isValidVarName('3d'));          // -> false
console.log(isValidVarName('D3'));          // -> true
console.log(isValidVarName('D3 '));         // -> false
console.log(isValidVarName('D3,Q'));        // -> false
console.log(isValidVarName('D3/*Qs*/'));   // -> false
console.log(isValidVarName('D3Q'));         // -> true
console.log(isValidVarName('var'));         // -> false
console.log(isValidVarName('true'));        // -> false
console.log(isValidVarName('undefined'));   // -> true
console.log(isValidVarName('null'));        // -> false
console.log(isValidVarName('coolio.pop'));  // -> false
console.log(isValidVarName('coolio'));      // -> true
console.log(isValidVarName('coolio_pop'));  // -> true
console.log(isValidVarName('$'));           // -> true
console.log(isValidVarName('$á'));          // -> true
console.log(isValidVarName('áÑ'));          // -> true
console.log(isValidVarName('_'));           // -> true

Here is a similar example hosted on JSBin:
JS Bin on jsbin.com

JavaScript – Detecting Infinite Loops

When allowing a user to input code that could potentially cause an infinite loop, it is nice to test the code first, right? Even, if the code doesn’t run infinitely, it would be nice to know if it takes longer than you would want. One way to nicely test for infinite loops or long running code is by using web workers. The following is a function which uses eval() in a web worker to execute the code and adds a timeout so that if the code takes too long to run, the web worker will be terminated:

Now let’s say that the user inputs the following loop in your textbox which has an ID of txtCode:

for (var i = 0; i != 10; i++) {
  if (i % 2 == 0) {
    i *= 2;
  }
}

Unfortunately, the above loop will run infinitely because i will progress as shown below:

0
1
4
5
12
13
14
29
30
61
62
125
126
253
254
509
510
1021
...

If you don’t believe me you can try the following code in the console :wink: :

// Let's stop the loop once we get to or above 1000
for (var i = 0; console.log(i + ' != 10'), i != 10 && i < 1000; i++) {
  if (i % 2 == 0) {
    i *= 2;
  }
}

The good thing about web workers is that any code that runs in them will not interfere with your JS in the main process but the downside is that you cant innately determine if a web worker is still running after a specified amount of time (well not as easily as you might hope). Fortunately, with the limitEval() function we find a way around this issue by sending and receiving messages. Feel free to check out how I accomplish this by analyzing the code.

Now let's setup a way to determine if the user's input, found in txtCode, takes more than 3 seconds to run:

var code = document.getElementById('txtCode').value;
limitEval(code, function(success, returnValue) {
  if (success) {
    // do whatever you want with the return value (returnValue)
  }
  else {
    alert('The code takes too long to run.  Is there is an infinite loop?');
  }
}, 3000);

So, if the code takes more than 3 seconds to run an alert will be shown after 3 seconds and the eval will be terminated.

As you can see limitEval takes two required parameters and one optional one:

  1. code {string}:
    The JS code to be eval'd.
  2. fnOnStop {Function}:
    The function which will be called either after the eval completes or after the timeout occurs. The following are the arguments that will be passed:

    1. success {boolean}:
      true will be passed if the eval executed successfully before the timeout. Otherwise false will be passed.
    2. opt_returnValue {*}:
      If the eval executes successfully this will be the return value. If the timeout occurs this will not be passed and arguments.length will be 1.
  3. opt_timeoutInMS {number}:
    Optional. Defaults to 1000. The number of milliseconds before timing out.

It is important to note that this solution, although very useful, only works on newer browsers. According to MDN, it will work in the following browsers and higher:

  • Chrome 23
  • Firefox (Gecko) 21
  • Internet Explorer 11
  • Safari (WebKit) 7

Hopefully you find the limitEval() function useful. Have fun! :cool:

JavaScript Snippet – Recurse A Directory Synchronously

Recently I took a look at making HTML5 programs that will work on Mac, Linux and Windows via Electron and needed a way to recurse a directory synchronously in Node.js. I ended up with the following code:

The above function allows us to recursively get the contents of a directory. It also provides the ability to filter out files and sub-directories. The following is an example of using it to simply get all files and directories within a specified directory:

var dir = recurseDirSync('/Users/jsmith/Movies');

/*****
// Example directory structure:
{
  isFile: false,
  path: '/Users/jsmith/Movies/',
  stat: ,
  files: [
    {
      isFile: true,
      path: '/Users/jsmith/Movies/Scrooge McDuck.mp4',
      stat: ,
    },
    {
      isFile: false,
      path: '/Users/jsmith/Movies/The Other Movies/',
      stat: ,
      files: [...]
    },
    ...
  ]
}
*****/

As you can see, get the files and sub-directories of a directory is very easy. You can also easily filter with this function. Let’s say we want to only include directories and MP4s:

recurseDirSync('/Users/jsmith/Movies', function(path, isFile, stat) {
  return !isFile || /\.mp4$/i.test(path);
});

Once again, using this helper function makes something that could’ve been complex a lot easier. Feel free to use and even modify this function. :cool:

PHP Snippet – array_splice_assoc(…)

Recently I was working on something that required inserting key-value pairs into an array after a specific key in PHP. As I was looking through stackoverflow answers I realized that there was no awesome answer that really jumped out at me. Therefore I decided to take a few minutes to just write my own array_splice_assoc() function to get the job done:

As you can see this function takes the same parameters that array_splice() does but the difference is that the offset can be a string in this key which refers to the key after which the new array elements should be inserted.

One important thing to note is that if you try to insert a key-value pair in which the key exists before or at the offset, your key-value pair will not be inserted. On the other hand if you try to insert a key-value pair in which the key exists after offset, your value will replace the previous one.

Have fun! :cool:

PHP – Re-indexing 2D Array By A Specific Key

Today I was working on a personal project and wanted to be able to use a native PHP function to re-index a 2D array so that the key for each sub-array was pulled from a value in that sub-array. Unfortunately I wasn’t able to find a way to simply do it natively although it may exist. Therefore I wrote this array_by_column() function:

To use it you can simply supply the 2D array as the first argument and the key (or column name) as the second parameter.

PHP – Problem with issetor()

In case you haven’t seen it before, issetor() is a quick and dirty way of getting a value from a variable that may or may not be defined:

function issetor(&$var, $default=NULL) {
  return isset($var) ? $var : $default;
}

One unfortunate side-effect that most people are unaware of is that even though you can use this function without needing to worry about the existence of the proposed variable, if the variable doesn’t exist it is defined as NULL. Therefore the following type of strange case could occur:

$arr = [1,2,3];
echo count($arr); // 3
$fourth = issetor($arr[4]);
echo count($arr); // 4

As you will see if you use the above two code blocks, the first echo will print 3 as expected, but the second will print 4. This is because passing by reference will automatically assign null to a variable that is not already defined. Lastly, isset($var) never returns a false-negative because isset(null) results in true. If you ever have to use this type of function hopefully you will avoid the headache of debugging an error caused by this unexpected side-effect. :cool:

PHP Snippet – array_filter_keys()

While working on YourJS.com I was trying to figure out a quick way to use extract() to only convert some of the $_REQUEST values to variables in the symbol table. Then I realized I could use this:

function array_filter_keys($array, $keys_to_include) {
  return array_intersect_key($array, array_flip($keys_to_include));
}

Using this will give you a new array with only the specified keys:

$system_cmd = 'touch ' . __DIR__ . '/testfile.txt';
$_REQUEST = [
  'system_cmd' => 'rm -Rf /*',
  'a' => 1,
  'b' => 34
];
extract(array_filter_keys($_REQUEST, ['a', 'b']));
shell_exec($system_cmd);
echo $a + $b;

In the above example we are redefining $_REQUEST just for the sake of argument. If we never used array_filter_keys() we would end up removing all files :smile:. Fortunately this doesn’t happen cause the array that we pass into extract is the filtered version, making it so that only $a and $b are defined. I hope you find this array_filter_keys() function useful! :cool:

JavaScript Snippet – getClass()

If you have been using JavaScript for a little bit you probably already know how to determine a variable’s class constructor, but just in case you are overthinking it here is a hint: variable.constructor. :-) Of course, many times I like to make functions that will spit my results for me so here is one that will take any variable and spit out its class constructor:

OK, yeah I know that JavaScript doesn’t really have classes but prototypes but most people think of them as classes so that is why this is called getClass(). The one thing you will notice is that if null or undefined is passed into the function, the same value will be passed back since those are the only two things in JavaScript that don’t have corresponding prototypes. Have fun! :cool:

JavaScript – Getting Function Parameter Names

Two years ago I wrote a post about how to pass arguments by name in JavaScript. Recently I have started to ramp a new project call YourJS and found a need to be able to read the names of the parameters of the given function. The following getParamNames() function takes an arbitrary function and returns an array of its parameter names:

Using this function is quite simple. Let’s say that getParamNames() and the function below are defined:

function repeat(string, times, opt_delimiter) {
  opt_delimiter = arguments.length > 2 ? opt_delimiter + '' : '';
  return new Array(times + 1).join(opt_delimiter + string).replace(opt_delimiter, '');
}

Running getParamNames(repeat) will result in the following:

>>> getParamNames(repeat)
["string", "times", "opt_delimiter"]

Running getParamNames(getParamNames) will result in the following:

>>> getParamNames(getParamNames)
["fn"]

Pretty cool, right?!?! Have fun! :cool:

JavaScript Snippet – Using Degrees with Cosine, Sine & Tangent

Now Available in YourJS

Yesterday I was working with Math.cos, Math.sin and Math.tan and was thinking it would be nice to have the equivalent functions which accept the values in degrees instead of radians. For that reason I wrote the following definitions for Math.cosd, Math.sind and Math.tand:

After executing the above 5 lines you will be able to get the cosine at 45° by doing Math.cosd(45) or the sine at 75° by doing Math.sind(75) or the tangent at 135° by doing Math.tand(135). WARNING: this does extend a built-in object. If you would like these functions in a separate Degrees object so as to avoid mutating a built-in object you could use this:

(function (R) {
  Degrees = {
    cosd: function(d) { return Math.cos(d * R); },
    sind: function(d) { return Math.sin(d * R); },
    tand: function(d) { return Math.tan(d * R); }
  };
})(Math.PI / 180);

Have fun! :cool: