hawkflyzy
2008-12-16 15:52
浏览 297

一个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);这个语法的意思是什么?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • rednaxelafx 2008-12-16 16:48
    已采纳

    这段代码看起来有点问题。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]

    已采纳该答案
    打赏 评论
  • samungtered 2008-12-16 16:32

    首先不说你这个代码写的是否正确啊
    直说你后面的那个问题
    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]

    打赏 评论

相关推荐 更多相似问题