我的目标是在编写干净代码的同时使用闭包。我注意到的一件事是,不知怎的,我总是最终重复自己,因为在一个以上的情况下需要我的一个匿名函数。
为了达到这个目标,我希望将这些重复的函数存储在一个对象中,以后我可以重用它。
现在,我的问题。我创建了此示例http://jsfiddle.net/tiagoespinha/tTx64/,并且警报不会触发,因为y
为空。
但是,如果我内联函数,一切正常http://jsfiddle.net/tiagoespinha/tTx64/1/
有解决这个问题的伎俩吗?我怎样才能在第一个例子中使用它?变量y
仍然存在,为什么JS不能抓住它?
答案 0 :(得分:1)
您希望对象具有自己的变量(y)和共享函数。
你真正需要的可能是原型。
function Holder() {
this.y = 5;
this.myFn();
}
Holder.prototype.myFn = function() {
alert("The value of the closure var is " + this.y);
}
new Holder();
我建议阅读Introduction to Object-Oriented JavaScript,这样你就不会尝试只用闭包来重建OOP。
答案 1 :(得分:1)
//our constructor, each instance will carry a y of 5
function Proto() {
this.y = 5;
}
//a shared function for all instances
Proto.prototype.returnedFn = function() {
alert("The value of the closure var is " + this.y);
}
//just a wrapper for the new instance call.
//I just like it this way to avoid using "new" when making instances
function newFn() {
//return a new instance
return new Proto();
}
//test it out
newFn().returnedFn();
newFn().returnedFn();
答案 2 :(得分:1)
您的第一个示例需要某种动态范围才能工作。 Javascript是静态范围的。
Closures允许函数从其定义的范围中捕获一些局部变量。Holder.myFn
未在包含变量y
的范围中定义。
另请注意,函数的每个实例都有自己的闭包。因此,不可能只定义一次函数,并且在不同的上下文中引用它们不同的y
。 (在你的第二个例子中,每次你调用newFn
时都会定义内部函数,因此可以存在许多实例,每个实例都有自己的y
副本。)
答案 3 :(得分:0)
我还会在我自己的问题上添加一个答案来报告我的发现。
根据提供的其他解决方案和部分使用OOP解决方案,我找到了另一种也使用闭包的方法。
// Object prototype which takes an argument
function MyObj(abc) {
// Declare function using a closure
// and thus being able to use the argument
this.myFn = (function(){
return function() {
alert("abc is " + abc);
};
})();
}
// Then we can simply create an object with the
// desired argument and the function will behave as expected
var v = new MyObj(10);
v.myFn();
我认为没有人提供这个解决方案可能是因为我省略了我并不想将值存储在对象中。我只是想传递一些值,在一个函数中使用它们然后去除对象。
在这种情况下,我认为纯粹的OOP解决方案可能过度。
无论如何,感谢所有提议的解决方案!