Q:

Can the javascript .bind go up multiple levels?

I have a piano Keyboard object in JavaScript and JQuery, like so:
function Keyboard(name, size, xPos, yPos, octaves) {
    this.name = name;
    this.size = size;

    this.setDimensions = function (){};

    this.highlightKeyboard = function (){};
    ...
    etc.
}

It's got a bunch of methods to set dimensions, generate the keyboard using divs for the keys, generate major and minor scales referencing the classes of the divs, etc.
I wrote 4 methods to highlight a major scale when I press a  certain key, a minor scale when I press a different key, major and minor triads with two other keys. They all worked, but after writing them I realized all 4 methods use a lot of the same code so I've been trying to consolidate by bringing out most of the code into separate methods in the main Keyboard object so I can call them repeatedly.
The problem I'm having now that I'm consolidating is getting the $(document).keypress objects to play nice with the external code.
What I want is something like this (partial code sample—I left out all the code to generate the keyboard and everything else that wasn't relevant because it seems to be working OK other than this one issue):
function Keyboard(name, size, xPos, yPos, octaves) {

    this.getMajorTonic = (function(userNote) {
        // code to determine myTonic
        return myTonic;
    });

    this.setMajScale = function(myTonic) {
        var scale = [];
        // code to determine scale[];            
        return scale;
    };

    this.setScaleClasses = function(scale) {
        // code to determine scale_classes[]
        return scale_classes;
    };

    this.highlightKeyboard = function (scale, scale_classes){};
        // code to add highlighted classes to my divs based
        // on the values in scale and scale_classes 
    };

    this.findMajorScales = function(userNote);
        var myTonic = this.getMajorTonic(userNote);
        var scale = this.setMajScale(myTonic);
        var scale_classes = this.setScaleClasses(scale);
        var highlightKeyboard = this.highlightKeyboard;

        $(document).keypress(function (event) {        
            if (event.which === 109) {
                highlightKeyboard(scale, scale_classes)    
            }
        });
    };
}

var keys = new Keyboard("piano", 1, 0, 0, 2);
keys.findMajorScales("E");

The desired effect is that when I load the page, it generates a blank keyboard, but when I press the "m" key, it highlights the E Major scale using the this.highlightKeyboard method. So I want to pass the this.findMajorScales method a this.highlightKeyboard method with no arguments, and then have the arguments filled in and the method executed when the "m" key is pressed. Most everything works, including the ($document).keypress object—it executes other code, just not the this.highlightKeyboard method with the right arguments.
How do I accomplish this? Does .bind have something to do with it? I can't really figure out if it's applicable here or if I need to do something else.
Thanks so much!
Jake

A:

So I want to pass the this.findMajorScales method a this.highlightKeyboard method with no arguments, and then have the arguments filled in and the method executed when the "m" key is pressed.

You are listening for M fine, so the only problem you have is invoking highlightKeyboard in the correct context.
Consider
var foo = {bar: function () {return this}),
    bar = foo.bar;

What will foo.bar() return? (foo)
What will bar() return? (window or null or throws an error, etc)

You have a lot of options
There are several ways around this, you've already mentioned Function.prototype.bind and it may be conceptually easier for you to use Function.prototype.call, Function.prototype.apply or even passing the this variable through using another identifier instead.
In either case, the default this in the handler will no longer be an instanceof Keyboard as the event is coming from document
Using Function.prototype.bind you have a few options
var highlightKeyboard = this.highlightKeyboard.bind(this);
$(document).keypress(function (event) {        
    if (event.which === 109) {
        highlightKeyboard(scale, scale_classes);
    }
});

// or binding args ahead of time too

var highlightKeyboard = this.highlightKeyboard.bind(this, scale, scale_classes);
$(document).keypress(function (event) {        
    if (event.which === 109) {
        highlightKeyboard();
    }
});

// or binding the handler

$(document).keypress(function (event) {        
    if (event.which === 109) {
        this.highlightKeyboard(scale, scale_classes);
    }
}.bind(this));

Using Function.prototype.call or .apply, requires ref to this
var highlightKeyboard = this.highlightKeyboard;
var me = this;

$(document).keypress(function (event) {        
    if (event.which === 109) {
        highlightKeyboard.call(me, scale, scale_classes);
    }
});

Just using a ref to this
var me = this;

$(document).keypress(function (event) {        
    if (event.which === 109) {
        me.highlightKeyboard(scale, scale_classes);
    }
});

Finally, one more solution is to write a function which generates what you want, this is very similar to what .bind is doing but is supported in environments that don't support .bind (read: legacy)
$(document).keypress(function (me) { // this function generates the inside one
    return function (event) { // this is the function used as the handler
        if (event.which === 109) {
            me.highlightKeyboard(scale, scale_classes);
        }
    };
}(this)); // passing in `this` as param `me`

