gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 00:07:49 25 4
gpt4 key购买 nike

我在 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 与它有什么关系吗?我真的不知道它是否适用于这里或者我是否需要做其他事情。

非常感谢!

jack

最佳答案

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.

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

考虑

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

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

<小时/>

你有很多选择

有几种方法可以解决这个问题,您已经提到了 Function.prototype.bind从概念上来说,使用 Function.prototype.call 可能更容易, Function.prototype.apply或者甚至通过使用另一个标识符来传递 this 变量。

无论哪种情况,处理程序中的默认 this 将不再是 Keyboard 的实例,因为事件来自 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)(读取:遗留)

$(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`

关于javascript - javascript .bind 可以上升多个级别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31190985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com