所以,我仍在阅读 Apress Pro Javascript 技术,但我在闭包方面遇到了麻烦。
正如约翰·雷西格所说:
闭包允许您引用父函数中存在的变量。
然而,它在创建变量时并不提供变量的值;它提供父函数中变量的最后一个值。这是最常见的问题,您会在 for 循环期间看到此情况。有一个变量被用作 interaor(例如,i)。在 for 循环内部,正在创建新函数,利用闭包再次引用迭代器。 rp问题是在调用新的闭包函数时,它们将引用迭代器的最后一个值(即数组中的最后一个位置),而不是您期望的值。
然后他在清单 2-16 中展示了一个使用匿名函数来引入作用域的示例。
/**
* Listing 2-16. Example of Using Anonymous Functions to induce the
* Scope Needed to Create Multiple Closure-Using Functions
*/
// An element with an ID of main
var obj = document.getElementById("main");
// An array of items to bind to
var items = ["click", "keypress"];
for (var i = 0; i < items.length; i++) {
// Use a self executed anonymous function to induce scope
(function() {
// Remembre the value within this scope
var item = items[i];
// Bind a function to the element
obj["on" + item] = function() {
// item refers to a parent variable that has been successfully
// scoped within the context of this loop
alert("thanks for your " + item);
};
})();
}
此示例按预期工作,并且主对象的行为是正确的。
接下来,它在迭代期间再次使用自执行函数来引入范围。
该函数的目的是创建一个对象,为其所有属性定义 getter 和 setter。在这种情况下,该示例不起作用。
/**
* Listing 2-25. Example of Dynamicaaly Generated Methods That Are Created
* When a New Object is instantiated
*/
// Create a new user object that accepts an object of properties
function User(properties) {
// Iterate thorugh the properties of the object, and make sure
// that it's properly scoped (sas discussed previously)
var that = this;
for (var i in properties) {
(function() {
console.log("property: " + i);
// Create a nwe getter for the property
that["get" + i] = function() {
return properties[i];
};
// Create a new setter for the property
that["set" + i] = function(val) {
properties[i] = val;
};
})();
}
}
// Create a new user object instance and pass in an object of
// properties to seed it with
var user = new User({
name: "Bob",
age: 44
});
// Just note that the name property does not exists, as it's private within the
// properties object
alert(user.name == null);
// However, we're able to access its value using the new getnaem()
// method that was dynamically generated
console.log("name: " + user.getname()); // name: 44 :(
alert(user.getname() == "Bob");
// Finally, we can see that it's possible to set and gt the age using
// the newly generated functions
user.setage(22);
alert(user.getage() == 22);
相反,在将 i 参数作为参数传递给自执行函数之后,它就可以工作了。
for (var i in properties) {
(function(prop) {
console.log("property: " + i);
// Create a nwe getter for the property
that["get" + prop] = function() {
return properties[prop];
};
// Create a new setter for the property
that["set" + prop] = function(val) {
properties[prop] = val;
};
})(i);
}
我的问题是:
- 为什么第一种情况(for循环)不需要传i参数,而
在第二个(for in)中,需要它才能正常工作吗?