views:

282

answers:

4

I am currently working on a project with some help and it has been going well, until this incident.

  function runCommand(commandString)
  {
   commands = new Object();
   commands.clear = function(){ $('#terminal').html('') }

   parameters = commandString.split(" ");
   command = parameters.shift();
   if( commands.hasOwnProperty(command)){
    commands[command](parameters);
   }
   else
   {
    $('#terminal').append(command+' command not recognized.'+'<br>');
   }
  }

The person who was helping me made this function, so I could run the "terminal-like" browsers that I needed to work on.

It works fine when using Firefox, heres an example:

guest@shell:/$ sudo make me sandwich
sudo command not recognized.
guest@shell:/$ clear

*clears*

guest@shell:/$ clear

But under google chrome this happen:

guest@shell:/$ sudo make me sandwich
sudo command not recognized.
guest@shell:/$ clear
clear command not recognized.

I believe that it has something to do with "commands.hasOwnProperty(command)" that is preventing it from working properly.

I am using JQuery the javascript library to build the website, and I need to know how to solve this problem, or an alternative.

+1  A: 

Works for me in Chrome 3.0.195.38.

I have never heard of any problems with hasOwnProperty in Chrome. I suspect your problem lies elsewhere. Full test case? How are you reading the commands in? Is it possible you are getting a command with leading whitespace in Chrome?

You should remember to declare local variables in your function (commands, parameters etc.) as var, otherwise you are getting accidental globals, which can produce odd and hard-to-debug errors, though I'd doubt that was the problem here.

bobince
A: 

I bet the problem is with differences in how "split" works between Firefox and Chrome.I would try changing the way that you get the parameters and the command:

var command = commandString, parameters = [];
if (/ /.test(command)) {
  parameters = command.split(' ');
  command = parameters[0];
  parameters = parameters.slice(1);
}

edit on second thought that should make no difference; as far as I can tell Safari should handle the simple "split on space" thing just fine. Make sure that you add some debugging around that code to see what "command" is when the function thinks it can't find "clear" in the object. And as @bobince says, define your variables with var!!!!

Pointy
So what *are* the differences in how "split" works between Firefox and Chrome?
Crescent Fresh
Mostly the "split()" vagaries among browsers have to do with regex arguments (like `foo.split(/\d/)` for example). See http://blog.stevenlevithan.com/archives/cross-browser-split
Pointy
A: 

I very highly doubt Chrome has any problems with hasOwnProperty, but in either case I cleaned up your code and changed the hasOwnProperty check into a typeof check, which should also be slightly more robust:

var runCommand = (function () {
    var terminal = $('#terminal');

    var commands = {
        clear: function () {
            terminal.html('');
        }
    };

    return function (commandString) {
        var parameters = commandString.split(" ");
        var command = parameters.shift();

        if (typeof commands[command] === "function") {
            commands[command](parameters);
        } else {
            terminal.append(command + ' command not recognized.<br />');
        }
    };
}());

...in case you're curious, I'm storing the commands object in a closure, that way it only needs to be created once, rather than being created/destroyed every time the function is run. This is dramatically faster, obviously.

Also, I'm only running a single search for the #terminal element, then storing it in a variable and using that. This is also for performance, since running a jQuery search is much more expensive than storing the result and using it repeatedly.

Pauan
A: 
function runCommand(commandString) {
    var terminal = $('#terminal'), //cached to reduce calls to jQuery
    commands = {    //start object literal, continue var statement
        clear: function (){ 
            terminal.html(''); 
        }
    },
    parameters = commandString.split(' '),
    command = parameters.shift(); //end var statement
    if (commands.hasOwnProperty(command)) {
        commands[command].call(parameters);
        console.log(command + ' command sent.'); //output for testing
    } else {
        terminal.append(command + ' command not recognized.<br>');
        console.warn(command + ' command not recognized.'); //output for testing
    }
}
AutoSponge