Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute function in command pattern JavaScript

Tags:

javascript

I am currently in the mist of reading Addy Osmani's JavaScript Design Patterns which can be found here: http://addyosmani.com/resources/essentialjsdesignpatterns/book/.

I am finding it quite enjoyable and very helpful. I do have a question about one of the patterns in the book, namely the Command Pattern.

In the book, Addy explains the Command Pattern is helpful to decouple objects and method calls a little better.

Here is my version of his example:

var person = {
    sayName: function (name) {
        return "My name is " + name;
    },
    sayAge: function (age) {
        return "My age is " + age;
    },
    sayGender: function (gender) {
        return "My gender is " + gender;
    }
}
person.execute = function (name) {
    return person[name] && person[name].apply(person, [].slice.call(arguments, 1));
}
console.log(person.execute("sayName", "Sethen"));

The magic is done in the execute method. As you can see, you pass the method name and arguments and the method takes care of the rest.

My confusion stems from what the execute method is actually returning. When you look at it, it looks like a short circuit with the && which I always thought returned a boolean due to JavaScript conversion.

However, if you try the code it works exactly as it should, logging My name is Sethen.

Furthermore, I've found that simply using return person[name].apply(person, [].slice.call(arguments, 1); produces the same results and in my mind much easier to read.

So, my question is how the return works in the original execute method:

return person[name] && person[name].apply(person, [].slice.call(arguments, 1));

and how the && operator works in this instance to make it work??

like image 540
Sethen Avatar asked Mar 24 '23 02:03

Sethen


2 Answers

The && operator does not always return boolean. It returns the value of the last subexpression it evaluates. If the requested method name exists, then that expression will return the result of the .apply() call.

So:

return person[name] && person[name].apply(person, [].slice.call(arguments, 1));

means:

if (!person[name])
  return person[name];

return person[name].apply(person, [].slice.call(arguments, 1));
like image 196
Pointy Avatar answered Apr 02 '23 10:04

Pointy


In this case the && is acting sort of like an if statement.

If you were to pass in something that was not a method on that object it would be false, and not continue to execute the rest of the statement.

like image 26
Morgan ARR Allen Avatar answered Apr 02 '23 10:04

Morgan ARR Allen