javascript .bind可以上升多个级别吗?

时间:2015-07-02 17:28:55

标签: javascript jquery bind

我在JavaScript和JQuery中有一个钢琴键盘对象,如下所示:

function Keyboard(name, size, xPos, yPos, octaves) {
    this.name = name;
    this.size = size;

    this.setDimensions = function (){};

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

它有一堆方法来设置尺寸,使用div键生成键盘,生成引用div类的主要和次要尺度等。

当我按下某个键时,我写了4个方法来突出显示一个主要音阶,当我按下不同的键时,我写了一个小音阶,用另外两个键按下主要和次要三和音。它们都有效,但在编写之后我意识到所有4种方法都使用了大量相同的代码,所以我一直试图通过将大部分代码放入主要的Keyboard对象中的单独方法来进行整合,以便我可以重复调用它们。

我正在整合的问题是让$(document).keypress个对象与外部代码一起玩得很好。

我想要的是这样的事情(部分代码示例 - 我遗漏了生成键盘的所有代码以及其他所有不相关的代码,因为除了这个问题之外它似乎正常工作):

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");

所需的效果是,当我加载页面时,它会生成一个空白键盘,但是当我按下“m”键时,它会使用this.highlightKeyboard方法突出显示E大调。所以我想传递this.findMajorScales方法没有参数的this.highlightKeyboard方法,然后填写参数,并在按下“m”键时执行方法。大多数一切都有效,包括($document).keypress对象 - 它执行其他代码,而不是具有正确参数的this.highlightKeyboard方法。

我如何做到这一点? .bind与它有关吗?我无法弄清楚它是否适用于此处,或者我是否需要做其他事情。

非常感谢!

杰克

2 个答案:

答案 0 :(得分:1)

  

所以我想传递this.findMajorScales方法一个没有参数的this.highlightKeyboard方法,然后填入参数并在" m"键被按下了。

您正在侦听 M ,所以唯一的问题是在正确的上下文中调用highlightKeyboard

考虑

var foo = {bar: function () {return this}),
    bar = foo.bar;

foo.bar()将返回什么? (foo
bar()将返回什么? (windownull或抛出错误等)

你有很多选择

有几种解决方法,您已经提到过Function.prototype.bind,从概念上讲,您可以更轻松地使用Function.prototype.callFunction.prototype.apply甚至传递{{1}通过使用另一个标识符来改变变量。

在任何一种情况下,处理程序中的默认this将不再是键盘的实例,因为事件来自this

使用document您有几个选项

Function.prototype.bind

使用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)); Function.prototype.call,需要参考.apply

this

只需使用参考var highlightKeyboard = this.highlightKeyboard; var me = this; $(document).keypress(function (event) { if (event.which === 109) { highlightKeyboard.call(me, scale, scale_classes); } });

this

最后,还有一个解决方案是编写一个生成所需内容的函数,这与var me = this; $(document).keypress(function (event) { if (event.which === 109) { me.highlightKeyboard(scale, scale_classes); } }); 正在做的非常相似,但在不支持.bind的环境中受支持(阅读:遗产)

.bind

答案 1 :(得分:0)

在Keyboard对象中没有名为highlightScales的方法。我认为你的意思是this.highlightKeyboard

话虽如此 - bind()用于将上下文传递给方法。它允许您手动设置this,而不是使用该范围内的任何this