一个JAVASCRIPT面向对象编程的问题

function User(properties){
for(var p in properties){(function(which){
var i = p;
which("get" + i)=function(){
return properties[p];
};
which("set" + i)=function(val){
properties[p] = val;
};
})(this);
}
}
哪位高手可以分析下这段代码,特别是var i = p;为什么必须要使用这句,还有(function(which){})(this);这个语法的意思是什么?

这段代码看起来有点问题。Anyway,先从简单的开始讲。
code="js" { })(this)[/code]
的意思就是定义一个匿名函数,并以this作为参数来调用。
注意到JavaScript的函数是不限制调用时提供的实际参数个数的,这里的which只是说如果调用的时候给了一个或多个参数,那么第一个参数叫做which。
这么做主要是为了避免直接使用this。JavaScript里的this的语义跟其它主流的面向对象语言有点不同,所以这种做法也算是JavaScript里相对独特的了。关于this,我以前简单记过一点,[url]http://rednaxelafx.iteye.com/blog/176500[/url]。

然后,var i = p这句的必要性在于p是定义在User函数里的,其作用域是整个函数的范围;它的值在for循环里会不停改变,而for循环的循环体里面是一个匿名函数,会形成闭包;如果不将其赋值给一个局部变量再使用的话……呵呵,你运行一下问题里的那段代码就知道会怎么样了:代码里有至少两种错误:
1、两个which()都应该是which[](不是圆括号而是方括号);这个不修改连运行都运行不了。
2、两个property[p]都应该是property[i]。
闭包带来的问题在第二种错误里就会表现出来。只要这样调用一下:
[code="js"]var u = new User({x:1, y:2, z:3})
for (var p in u) {
if (p.match(/^set/)) { // if the member is a setter, call it
up) // set the value to its original property name
}
}
for (var p in u) {
if (p.match(/^get/)) { // if the member is a getter, call it
alert(p + ' ' + up)
}
}[/code]
输入的参数是带有x、y、z三个属性的对象,所以应该生成getx/setx、gety/sety、getz/setz,最后看到输出应该是:
getx x
gety y
getz z
而实际执行问题中的代码会看到结果是:
getx z
gety z
getz z
这就说明有问题了。

把问题中的代码中两种错误改过来:
[code="js"]function User(properties) {
for (var p in properties) {
(function(which) {
var i = p;
which["get" + i] = function() {
return properties[i];
};
which["set" + i] = function(val){
properties[i] = val;
};
})(this);
}
}[/code]
可以看到行为就是期望中的行为了。关于闭包以前我记过C#/Ruby的,在这里:[url]http://rednaxelafx.iteye.com/blog/177604[/url]。JavaScript的状况跟C#的有点相似;不同的是虽然User函数里的变量p是在for循环里定义的,但它的作用域是覆盖了整个User函数的范围,而不是限制在for循环内的。这个我也稍微记过一点,这里:[url]http://rednaxelafx.iteye.com/blog/190347[/url]

首先不说你这个代码写的是否正确啊
直说你后面的那个问题
code="javascript"{
var i = p;
which("get" + i) = function(){
return properties[p];
};

                      which("set" + i) = function(val){
                          properties[p] = val
                      };
                  })(this);

[/code]

就是等价于
[code="javascript"]
var f = function(which){
var i = p;
which("get" + i) = function(){
return properties[p];
};

                      which("set" + i) = function(val){
                          properties[p] = val
                      };    

};
f(this);
[/code]

如果你不理解可以简单点使用下下面的
code="javascript"{
alert(arg);
})("hello, boy");
[/code]

和这段代码 在EditPlus上试下就知道了
[code="javascript"]
var f = function f(arg){
alert(arg)
}

f("hello, boy");

[/code]