var createCallback = function(method, context) {
    return function() {
        //the arguements is passed in when the this callback
        //method is call
        //if there is parameter passed
        //package the parameter with the context
        //into an array, an invoke the callback
        //method with the array
        var l = arguments.length;
        if (l > 0) {
            var args = [];
            for (var i = 0; i < l; i++) {
                args[i] = arguments[i];
            }
            //the last array member is the 
            //the context
            args[l] = context;

            //apply with array argument 
            return method.apply(this, args);
        }

        //if there is no parameters 
        //just invoke the callback method with
        // the context as the only parameter
        return method.call(this, context);
    }
}

function eat(foodName, animalName) {
    alert(animalName + " eat " + foodName);
}

function Animal(name) {
    if (!name) {
        this.name = name;
    }
    else {
        this.name = "animal";
    }

    //eat is the function will be called
    //name is the predetermined pass-in parameter
    //this parameter will be the last parameter in the function
    //the order paraemeter will be passed in when the callback is called
    this.eat = createCallback(eat, name);
}

var a = new Animal("fred");
//"grass" is passed in when callback is called
a.eat("grass");