Function.prototype.overloadSetter = function(usePlural){
        var self = this;
        return function(a, b){
            if (a == null) return this;
            if (usePlural || typeof a != 'string'){
                for (var k in a) {
                    self.call(this, k, a[k]);
                }
            } else {
                self.call(this, a, b);
            }
            return this;
        };
    };    Function.prototype.extend = function(key, value){
        this[key] = value;
    }.overloadSetter();
    function x() {    }
    x.extend('a',1);
这段JS不知道是什么意思,当我执行x.extend('a',1)的时候,为什么
function(a, b)接收到的参数就是a和1呢,麻烦哪位解释一下?谢谢了!

解决方案 »

  1.   

    先看这一句Function.prototype.extend = function(key, value){
            this[key] = value;
        }.overloadSetter();这句相当于Function.prototype.extend = function(key, value){
        function(a, b){
                if (a == null) return this;
                if (usePlural || typeof a != 'string'){
                    for (var k in a) {
                        self.call(this, k, a[k]);
                    }
                } else {
                    self.call(this, a, b);
                }
                return this;
            };
        
    }当执行这句x.extend('a',1);时
    就会执行这句this[key] = value;
    即this.a = 1;
      

  2.   

    楼主,我测试了一下。。并且网上找到
    该解释2.在javascript中有一个Function对象,所有自定义的函数都是Function对象类型的。Function对象接受的所有参数都是字符串类型的,其中最后一个参数就是要执行的函数体,而前面的参数则是函数真正需要接受的参数。如:var add = new Function("number","number1","alert(number+number1)");
      var add = new Function("number","alert(number+10)");等价于:function add(number,number1){   alert(number+number1);} function add(number){  alert(number+10); }也等价于:var add =function add(number,number1){   alert(number+number1);}var add = function(number){   alert(number+10);}所有自定义的函数都是Function类型的实例Function.prototype.extend = function(key, value){
            this[key] = value;
        }.overloadSetter();
    这句话是对Function类的原型增加定义一个extend函数,该函数是通过一个匿名函数调用overloadSetter方法
    所以实际上extend函数实体是(这里之所以能调用overloadSetter方法,同样道理,因为匿名函数的构造函数是Function,也就是Function类的实例化对象,所以匿名函数可以调用该类的方法overloadSetter,该方法的定义就是第一行代码了)
    并且其中的self参数是匿名函数: function(key, value){
            this[key] = value;
        }
    function(a, b){
                if (a == null) return this;
                if (usePlural || typeof a != 'string'){
                    for (var k in a) {
                        self.call(this, k, a[k]);
                    }
                } else {
                    self.call(this, a, b);
                }
                return this;
            };因此最后x.extend('a',1);表示调用x对象的所属类(Function)的方法extend 也就是上面说过的匿名函数function(a, b){
                if (a == null) return this;
                if (usePlural || typeof a != 'string'){
                    for (var k in a) {
                        self.call(this, k, a[k]);
                    }
                } else {
                    self.call(this, a, b);
                }
                return this;
            };
    所以这时候的this对象就是x本身了,并且上面说过self是指的匿名函数
    function(key, value){
            this[key] = value;
        }因此最后调用完成后的结果是对x对象增加一个属性名字为'a',值为1。
      

  3.   

    function(a,b) a和b两个参数没有引用key和value,请问它是怎么传值的呢?
      

  4.   

    这个函数function(a, b){
                if (a == null) return this;
                if (usePlural || typeof a != 'string'){
                    for (var k in a) {
                        self.call(this, k, a[k]);
                    }
                } else {
                    self.call(this, a, b);
                }
                return this;
            }没有被调用,感觉没有传值
      

  5.   

    我把最后一部分分解成几个块,相信你会明白<script type="text/javascript">
    Function.prototype.overloadSetter = function(usePlural) {
    var self = this; return function(a, b) {
    if (a == null)
    return this;
    if (usePlural || typeof a != 'string') {
    for ( var k in a) {
    self.call(this, k, a[k]);
    }
    } else {
    self.call(this, a, b);
    }
    return this;
    };
    };var fun2 = function(key, value) {
    this[key] = value;
    };var fun3 = fun2.overloadSetter();
    alert(fun3);//这才是x.extend('_a', 11)真正调用的函数Function.prototype.extend = fun3;function x() {
    }<script type="text/javascript">
    Function.prototype.overloadSetter = function(usePlural) {
    var self = this; return function(a, b) {
    if (a == null)
    return this;
    if (usePlural || typeof a != 'string') {
    for ( var k in a) {
    self.call(this, k, a[k]);
    }
    } else {
    self.call(this, a, b);
    }
    return this;
    };
    };var fun2 = function(key, value) {
    this[key] = value;
    };var fun3 = fun2.overloadSetter();
    alert(fun3);//这才是x.extend('_a', 11)真正调用的函数Function.prototype.extend = fun3;function x() {
    }
    var f = x.extend('_a', 11);</script>
    var f = x.extend('_a', 11);</script>
      

  6.   

    我设了断点监控,a和b是有值的,就是a和1
      

  7.   

    不小心复制了两次
    <script type="text/javascript">
    Function.prototype.overloadSetter = function(usePlural) {
    var self = this; return function(a, b) {
    if (a == null)
    return this;
    if (usePlural || typeof a != 'string') {
    for ( var k in a) {
    self.call(this, k, a[k]);
    }
    } else {
    self.call(this, a, b);
    }
    return this;
    };
    };var fun2 = function(key, value) {
    this[key] = value;
    };var fun3 = fun2.overloadSetter();
    alert(fun3);//这才是x.extend('_a', 11)真正调用的函数Function.prototype.extend = fun3;function x() {
    }
    var f = x.extend('_a', 11);//调用x.extend实际是调用Function.prototype.extend,也就是调用fun3,根本就是传说中的unction(a, b)</script>
      

  8.   

    哦,Function.prototype.entend = function(a, b){
                if (a == null) return this;
                if (usePlural || typeof a != 'string'){
                    for (var k in a) {
                        self.call(this, k, a[k]);
                    }
                } else {
                    self.call(this, a, b);
                }
                return this;
            }函数,也就是return的那个函数,当执行这句 x.extend('a',1)时,就是给形参a,b传参"a",1
      

  9.   

    太感谢了,经过这样一番解释终于看懂了
    这个函数的原型我是在mootools里看到的,为什么要设置得这么复杂呢?或者这样做有什么好处呢?
      

  10.   

    完整的代码是这样的var Function = this.Function;
        var enumerables = true;
        for (var i in {toString: 1}) {
            enumerables = null;
        }
        if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];    Function.prototype.overloadSetter = function(usePlural){
            var self = this;
            return function(a, b){
                if (a == null) return this;
                if (usePlural || typeof a != 'string'){
                    for (var k in a) {
                        self.call(this, k, a[k]);
                    }
                    if (enumerables) for (var i = enumerables.length; i--;){
                        k = enumerables[i];
                        if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
                    }
                } else {
                    self.call(this, a, b);
                }
                return this;
            };
        };    Function.prototype.extend = function(key, value){
            this[key] = value;
        }.overloadSetter();这样除了可以链式调用外,overloadSetter这个函数有什么用呢?
    overloadSetter = function(usePlural)  这个参数加上a和b是不是表示可以传3个参数啊?
      

  11.   

    在函数function(a, b) 里加以下两句,然后自己研究一下吧
    alert(self);
    alert(this);
      

  12.   


    overloadSetter有什么用?你这样看看是不是会明白点?这有点像是类似于注册命名空间的意思
    function x() {
            
        }
        x.extend("chr","csdn");
        x.extend({'a':function(){alert(this.b)},'b':2});
        x.extend("fn1",function(){alert(this.chr)});
        x.fn1.extend("fn2",function(a){
            alert(a);
        });
        alert(x.chr);//csdn
        x.a();//2
        alert(x.b);//2
        x.fn1();//csdn
        x.fn1.fn2('test');//test
      

  13.   


    谢谢你的回答,不过好像不是这么用的,我在网上找到一篇资料http://www.caoren.net/article/?id=37
    好像是为了提取公共方法用的