我是一名试验 JavaScript 的 C# 开发人员,我正在努力了解范围 :)
我有以下代码,其中包含一个 addEventListener,我想在其中使用我的对象中的一个字段:
(function(window) {
function Keyboard() {
this.keys = {};
}
Keyboard.prototype.handle_keydown = function(args) {
this.keys[args.keyCode] = true;
}
Keyboard.prototype.listen = function() {
window.addEventListener('keydown', this.handle_keydown);
}
app.util.keyboard = new Keyboard();
})(window);
我想在我的处理程序中使用键数组,但我知道我不能通过使用它来访问,因为这是该上下文中的窗口(正确吗?)。 如果我把它改成
app.util.keyboard.keys[args.keyCode] = true;
它有效,但我不确定这是修复它的好方法。
我找到了 this question ,这看起来很相似,但我不确定如何将它放入我的示例中。
感谢您的帮助!
最佳答案
一些事情:
大多数人会建议类似 var self = this 的内容因为它又快又简单。
但是var self = this不会将 View 对象与 View 逻辑完全分开,后者来自更正式的 C# 背景并查看您的代码,听起来像是您想做的事情。 p>
为了让回调仅在事件触发时执行,将处理程序包装在一个函数中,以便立即对其进行评估,但仅在出现 keydown 时执行。事件触发(参见下面的代码)。
理解 JS 中的范围:无论执行上下文是什么,也是当前范围。您的监听器已添加到 listen 上的方法(称为 Keyboard.prototype)中,但是 keydown事件实际上是在 window 上触发的-- 处理程序在与定义它的地方不同的上下文中执行;它在调用它的上下文中执行,在本例中为 window , 所以它的范围是 window除非你通过 bind 将它绑定(bind)到另一个对象或 apply当它被定义时。
在您的代码中,window是用户与之交互的 View ,Keyboard是那个 View 的 Controller 。在 MVC 模式中,就像您可能在 C#/.NET 中习惯的那样, View 不会告诉自己在事情发生时该做什么, Controller 会告诉 View 该做什么。因此,如果您要使用 var self = this 分配对 Controller 的引用像很多人一样, View 将自行管理——但仅限于 keydown 的特定处理程序。事件。这是不一致的,并且在大型项目中将变得难以管理。
解决方案:
Keyboard.prototype.listen = function() {
window.addEventListener('keydown', function(e) {
this.handle_keydown(e);
}.bind(this), false);
}
更好的解决方案:
Keyboard.prototype.view = window;
Keyboard.prototype.listen = function() {
this.view.addEventListener('keydown', function(e) {
this.handle_keydown(e);
}.bind(this), false);
}
最佳解决方案(直到 ES6 class 准备就绪):
// define
function addViewController(view) {
function ViewController() {
this.handle_keydown = function(args) {
// handle keydown events
};
this.listen = function() {
this.view.addEventListener('keydown', function(e) {
this.handle_keydown(e);
}.bind(this), false);
};
this.view = view;
return this;
}
return new ViewController(view);
}
// implement
var keyboard = addViewController(window);
keyboard.listen();
.bind()与 ECMAScript 5+ 兼容;如果您需要针对旧版浏览器的解决方案,Mozilla 发布了一个很好的替代品 .bind()使用 functions和 .call() :https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
编辑:这是您实例化的 keyboard对象看起来像使用这个新的模块化解决方案:
关于Javascript 作用域 addEventListener 和 this,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13996263/
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中
在尝试实现应用auto_orient的过程之后!对于我的图片,我收到此错误:ArgumentError(noimagesinthisimagelist):app/uploaders/image_uploader.rb:36:in`fix_exif_rotation'app/controllers/posts_controller.rb:12:in`create'Carrierwave在没有进程的情况下工作正常,但在添加进程后尝试上传图像时抛出错误。流程如下:process:fix_exif_rotationdeffix_exif_rotationmanipulate!do|image|
这段代码似乎创建了一个范围从a到z的数组,但我不明白*的作用。有人可以解释一下吗?[*"a".."z"] 最佳答案 它叫做splatoperator.SplattinganLvalueAmaximumofonelvaluemaybesplattedinwhichcaseitisassignedanArrayconsistingoftheremainingrvaluesthatlackcorrespondinglvalues.Iftherightmostlvalueissplattedthenitconsumesallrvaluesw
你能解释一下吗?我想评估来自两个不同来源的值和计算。一个消息来源为我提供了以下信息(以编程方式):'a=2'第二个来源给了我这个表达式来评估:'a+3'这个有效:a=2eval'a+3'这也有效:eval'a=2;a+3'但我真正需要的是这个,但它不起作用:eval'a=2'eval'a+3'我想了解其中的区别,以及如何使最后一个选项起作用。感谢您的帮助。 最佳答案 您可以创建一个Binding,并将相同的绑定(bind)与每个eval相关联调用:1.9.3p194:008>b=binding=>#1.9.3p194:009>eva
我是Ruby和RubyonRails世界的新手。我已经阅读了一些指南,但我在使用以下语法时遇到了一些麻烦。我认为在Ruby中使用:condition语法来定义具有某种访问器的类属性,例如:classSampleattr_accessor:conditionend隐式声明“条件”属性的getter和setter。当我查看一些Rails示例代码时,我发现以下示例我并不完全理解。例如:@post=Post.find(params[:id])为什么它使用这种语法访问id属性,而不是:@post=Post.find(params[id])或者,例如:@posts=Post.find(:all):
我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li
我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan