这可能有点抽象,但我正试图解决JavaScript闭包等问题。请使用以下代码:
function MyObj() {
var me = this;
this.foo = function(bar) {
// Do something with 'bar'
}
// Set up lots of local variables etc.
// ....
$(window).load(function() {
// Add a delegated click handler to specific <input> elements
$(document).on('click.myobj', 'input.special', function() {
// Do something with the <input> that triggered the click event
me.foo(this);
});
});
}
var myObj = new MyObj();
传递给它的匿名函数绑定到click事件会创建一个引用me
的闭包。我想知道的是,做这样的事情是否更好(避免关闭):
$(window).load(function() {
// Add a delegated click handler to specific <input> elements
(function(localMe) {
$(document).on('click.myobj', 'input.special', function() {
// Do something with the <input> that triggered the click event
localMe.foo(this);
});
})(me);
});
这是一个更好的方法,还是我过于偏执于创建一个闭包?或者,是否有“第三条道路”?
修改
此外,做这样的事情会更好:
$(window).load(function() {
// Add a delegated click handler to specific <input> elements
$(document).on('click.myobj', 'input.special', {localMe : me}, function(event) {
// Do something with the <input> that triggered the click event
event.data.localMe.foo(this);
});
});
答案 0 :(得分:1)
匿名函数现在在javascript中大量使用(作为参数和作用域/闭包的直接函数)。这没有性能问题。
但是你可能会遇到代码阅读问题。因为当您看到变量时,必须检查变量的来源。但这里没什么大不了的。
在你的第二个例子中,你仍然有一个关闭“休息”。因为在click
中的匿名函数中,您使用localMe
变量。 localMe
是你的功能之外的一个论点。
// Here, 'me' is a direct local variable.
$(window).load(function() {
// Here, we are in an anonymous fonction, so 'me' is not a direct variable anymore. But you still can access it.
// Add a delegated click handler to specific <input> elements
(function(localMe) {
// Here, 'localMe' is a direct local variable.
$(document).on('click.myobj', 'input.special', function() {
// We are in an anonymous function, so 'localMe' is not a direct variable anymore.
// Do something with the <input> that triggered the click event
localMe.foo(this);
});
})(me);
});
如果你真的想避免关闭“break”,你应该将你的函数绑定到你的对象。但请注意,并非每个浏览器都支持函数的bind
方法。
答案 1 :(得分:1)
后者(AFAIK)效率更高,但可能无法测量,除非在紧密循环中使用。
原因是所有变量解除引用都必须遵循范围链。在后一种情况下,变量localMe
可以在匿名函数的参数列表中找到。
在前一种情况下,在那里找不到变量,但在外部范围内。遍历范围链需要额外的时间。
答案 2 :(得分:1)
如果从构造函数绑定事件,您将始终创建一个闭包。实际上,您甚至需要闭包来保留对实例的引用。但是,您可能会这样做:
function MyObj() {
this.foo = function(bar) {
// Do something with 'bar'
}
// Set up lots of local variables etc.
// ....
}
var myObj = new MyObj();
$(function() {
$(document).on('click.myobj', 'input.special', function() {
myObj.foo(this);
});
});
如果你只创建构造函数的单例实例,那么无论如何都无关紧要。
答案 3 :(得分:0)
我可能会这样做:
var bind = function( fn, me ) { return function() { return fn.apply(me, arguments); }; },
Object = (function() {
function Object() {
this.handler = bind(this.handler, this);
// Add a delegated click handler to specific <input> elements.
$(document).on("click.myobj", "input.special", this.handler);
}
Object.prototype.foo = function( bar ) {
// Do something with "bar".
};
Object.prototype.handler = function( event ) {
// Do something with the <input> that triggered the click even.
return this.foo(event.currentTarget);
};
return Object;
})();
var obj = new Object();
这会使用 .apply 来跳过闭包和使用Ies的用法。不确定它是否更有效,但它是另一种选择。