0

I meet a problem about dynamic dispatch. The following is the code snippet which from the book [Programming JavaScript Applications], and I put it on https://jsfiddle.net/abramhum/bbfxxwok/1/

function equals(a, b, c) {
  console.log("a[=]" + a);
  if (a == b) {
    console.log(c);
  }
}

function test(a, fn) {
  console.log(a + " ---start function[=]");
  fn.apply(this);
  console.log(a + " ---Fnished");
}

var methods = {
    init: function(args) {
      return 'initializing...';
    },
    hello: function(args) {
      return 'Hello, ' + args;
    },
    goodbye: function(args) {
      return 'Goodbye, cruel ' + args;
    }
  },
  greet = function greet(options) {
    var args = [].slice.call(arguments, 0),
      initialized = false,
      action = 'init'; // init will run by default

    if (typeof options === 'string' &&
      typeof methods[options] === 'function') {
      action = options;
      args.shift();
    }
    return methods[action](args);
  };

test('Dynamic dispatch', function() {
  var test1 = greet(),
    test2 = greet('hello', 'world!'),
    test3 = greet('goodbye', 'world!');
  equals(test2, 'Hello, world!',
    'Dispatched to hello method.');
  equals(test3, 'Goodbye, cruel world!',
    'Dispatched to goodbye method.');
});

There exist two subjects in this problem, one is when greet("goodbye", "world") is executed, why it called greet(options), and the value about options is indeed the fist parameter, like "goodbye", and the "world" can be get via arguments; The second is var methods ={...}, it get the arguments like init, and return the value if matching the declare, like init:function(args){...}, but it indeed not code style of switch, and why we can use that in javascript. This is much unlike C codes, I don't know why, is any one know the reason? thanks.

abramhum
  • 443
  • 2
  • 8
  • 20

1 Answers1

2

one is when greet("goodbye", "world") is executed, why it called greet(options), and the value about options is indeed the fist parameter, like "goodbye", and the "world" can be get via arguments

Because in a JavaScript non-arrow function, arguments is a predefined identifier referring to a pseudo-array of all of the arguments passed to the function. It has nothing to do with dynamic dispatch. It's just a feature of JavaScript functions that was useful back before JavaScript got proper variable parameter lists:

function foo() {
  console.log("foo called, total arguments: " + arguments.length);
  for (var n = 0; n < arguments.length; ++n) {
    console.log("Arg #" + n + ":", arguments[n]);
  }
}
foo();
foo("bar");
foo("biz", 42);

the second problem is var methods ={...}, it get the arguments like init

Those aren't arguments, those are properties being defined for the object assigned to methods. Just like a, b, and c here:

var obj = {
    a: 42,
    b: "Whatever",
    c: "just cuz"
};

...and return the value if matching the declare, like init:function(args){...}, but it indeed not code style of switch, and why we can use that in javascript.

Because functions are objects, and so like any other object, you can refer to them from variables, arguments, and object properties. methods's properties init, hello, and goodbye refer to functions. You can call them via the properties: method.init().

So say we have the variable name containing "init". We can look up the property with that name on methods: methods[name]. And since that gives us a reference to a function, we can call that function.

var methods = {
    init: function() {
        console.log("init called");
    }
};
var name = "init";
methods[name](); // "init called"

More: Dynamically access object property using variable

This is much unlike C codes, I don't know why, is any one know the reason?

Because C and JavaScript are fundamentally different languages, created with different design constraints, at different times, by different people, with different priorities and limits.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875