设为首页收藏本站订阅更新

无忧脚本

 找回密码
 加入无忧

QQ登录

只需一步,快速开始

查看: 7073|回复: 30

[原创] 有意思的function扩展…… [复制链接]

Rank: 8Rank: 8

注册时间
2005-3-9
威望
1952
阅读权限
150
积分
4347
帖子
1577
精华
9
UID
24714
状态
当前离线
发表于 2008-4-11 21:58:42 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料 QQ 查看个人网站
一键分享 一键分享
[php]
<script>
Function.prototype.$bind=function(object)
{
        var callback = function (fn) {
                return fn;
        }
        with(object)
        {
                return eval('callback(' + this.toString() + ')');
        }
}

var obj={a:1,b:2};
var f=function (){
        a=10;
        b=11;
}.$bind(obj);
f();
alert(obj.a);
//----------------------------------------------------------------------------------------------------
G = {};
G.objInstanceOf = function(obj, c){
        if(typeof(c) == "string")
                return typeof(obj) == c;
        if(obj instanceof c || c.__templete__ && obj instanceof c.__templete__)
                return true;
        var _interfaces = obj && obj.__interfaces__;
        if(_interfaces)
                for(var i = 0, len = _interfaces; i < len; i++){
                        if(_interfafces == c)
                                return true;
                }
        return false;
};

G.objectAsPrototype = function(obj, c){
        c = c || function(){};
        c.prototype = obj;
        return c;
};

Function.prototype.getPrototypeObject = function(){
        var p = this.__templete__ || (this.__templete__= G.objectAsPrototype(this.prototype));
        return new p();
};

Function.prototype.$pextends = function(p){
        var me = this.$bind({$super:p});
        var ins = function()
        {       
                var ret = me.apply(this, arguments);
                return ret;
        }

        ins.prototype = p.getPrototypeObject();
        return ins;
};
//--------------------------------------------------------------------------------------------------------
function B(){};
var A = function(){
        alert($super);
}.$pextends(B);
var a = new A();
//---------------------------------------------------------------------------------------------------------
Function.prototype.$verify = function(){

        var me = this;
        var _args = arguments;
       
        //第一范式 [new] T <=> [new] R:function(){donothing, return T.apply},R.prototype = T.prototype
        var mins = function(){
                for(var i = 0, len = _args.length; i < len; i++)
                {
                        if(!G.objInstanceOf(arguments,_args)){
                                        throw new TypeError("函数的参数类型不匹配,位置:"+(i+1));
                        }
                }
                return me.apply(this, arguments);
        }
        mins.prototype = me.prototype;
       
        return mins;       
}
//-------------------------------------------------------------------------------------------------------
var foo = function(x,y){
        alert(x+y);
}.$verify("number","number");

foo(1,2);

var foo2 = function(x,y){
        x(y);
}.$verify(Function,"number");
//foo("error",2);

foo2(function(x){alert(x)},10);
//foo2("x","y");

var Class3 = function(x,y){
        this.x = x;
        this.y = y;
}.$verify("number","number");
Class3.prototype.dist2 = function(){return this.x*this.x + this.y*this.y};
var c = new Class3(10,20);
alert(c.dist2());

//--------------------------------------------------------------------------------------------------------
Function.prototype.$staticable = function()
{
        var me = this;
        var cache = [];
        var index = 0;

        var mins = function(){
                mins.alloc = function(){
                        cache[index] = cache[index] || {};
                        return cache[index++];
                };
                var ret = me.apply(this, arguments);
                mins.alloc = null;
                index = 0;
                return ret;
        }

        mins.prototype = me.prototype;

        return mins;
}
//----------------------------------------------------------------------------------------------------------
var Test = function(){
        var x = Test.alloc();
        x.a = x.a || 0;
        x.a++;
        return x.a;
}.$staticable();

for(var i = 0; i < 10; i++)
        alert(Test());
//-----------------------------------------------------------------------------------------------------------
Function.prototype.$protected = function(){
        var me = this;
       
        var mins = function(){

                var p = me.getPrototypeObject();

                var ret = function(){}; //create a new object

                for(var each in mins.prototype)  //clone prototypes
                {
                        if(mins.prototype[each] instanceof Function){
                                ret.prototype[each] = function(){
                                        return mins.prototype[each].apply(p,arguments);        //call by p
                                }
                                p[each] = mins.prototype[each];
                        }
                        else{
                                p[each] = ret.prototype[each] = mins.prototype[each];
                        }
                }
                me.apply(p,arguments);//clone a new object by me

                return new ret(); //return this object;
        }
        return mins;
}
//----------------------------------------------------------------------------------------------------------------
//将一个类型的this域声明为全部私有
var Test = function(x,y)
{
        this.x = x;
        this.y = y;
}.$protected();
Test.prototype.getX = function(){
        return this.x;
}
var t = new Test(5,10);
alert(t.x);
alert(t.getX());
</script>
[/php]
  1. <script>
  2. Function.prototype.$bind=function(object)
  3. {
  4.         var callback = function (fn) {
  5.                 return fn;
  6.         }
  7.         with(object)
  8.         {
  9.                 return eval('callback(' + this.toString() + ')');
  10.         }
  11. }

  12. var obj={a:1,b:2};
  13. var f=function (){
  14.         a=10;
  15.         b=11;
  16. }.$bind(obj);
  17. f();
  18. alert(obj.a);
  19. //----------------------------------------------------------------------------------------------------
  20. G = {};
  21. G.objInstanceOf = function(obj, c){
  22.         if(typeof(c) == "string")
  23.                 return typeof(obj) == c;
  24.         if(obj instanceof c || c.__templete__ && obj instanceof c.__templete__)
  25.                 return true;
  26.         var _interfaces = obj && obj.__interfaces__;
  27.         if(_interfaces)
  28.                 for(var i = 0, len = _interfaces; i < len; i++){
  29.                         if(_interfafces[i] == c)
  30.                                 return true;
  31.                 }
  32.         return false;
  33. };

  34. G.objectAsPrototype = function(obj, c){
  35.         c = c || function(){};
  36.         c.prototype = obj;
  37.         return c;
  38. };

  39. Function.prototype.getPrototypeObject = function(){
  40.         var p = this.__templete__ || (this.__templete__= G.objectAsPrototype(this.prototype));
  41.         return new p();
  42. };

  43. Function.prototype.$pextends = function(p){
  44.         var me = this.$bind({$super:p});
  45.         var ins = function()
  46.         {       
  47.                 var ret = me.apply(this, arguments);
  48.                 return ret;
  49.         }

  50.         ins.prototype = p.getPrototypeObject();
  51.         return ins;
  52. };
  53. //--------------------------------------------------------------------------------------------------------
  54. function B(){};
  55. var A = function(){
  56.         alert($super);
  57. }.$pextends(B);
  58. var a = new A();
  59. //---------------------------------------------------------------------------------------------------------
  60. Function.prototype.$verify = function(){

  61.         var me = this;
  62.         var _args = arguments;
  63.        
  64.         //第一范式 [new] T <=> [new] R:function(){donothing, return T.apply},R.prototype = T.prototype
  65.         var mins = function(){
  66.                 for(var i = 0, len = _args.length; i < len; i++)
  67.                 {
  68.                         if(!G.objInstanceOf(arguments[i],_args[i])){
  69.                                         throw new TypeError("函数的参数类型不匹配,位置:"+(i+1));
  70.                         }
  71.                 }
  72.                 return me.apply(this, arguments);
  73.         }
  74.         mins.prototype = me.prototype;
  75.        
  76.         return mins;       
  77. }
  78. //-------------------------------------------------------------------------------------------------------
  79. var foo = function(x,y){
  80.         alert(x+y);
  81. }.$verify("number","number");

  82. foo(1,2);

  83. var foo2 = function(x,y){
  84.         x(y);
  85. }.$verify(Function,"number");
  86. //foo("error",2);

  87. foo2(function(x){alert(x)},10);
  88. //foo2("x","y");

  89. var Class3 = function(x,y){
  90.         this.x = x;
  91.         this.y = y;
  92. }.$verify("number","number");
  93. Class3.prototype.dist2 = function(){return this.x*this.x + this.y*this.y};
  94. var c = new Class3(10,20);
  95. alert(c.dist2());

  96. //--------------------------------------------------------------------------------------------------------
  97. Function.prototype.$staticable = function()
  98. {
  99.         var me = this;
  100.         var cache = [];
  101.         var index = 0;

  102.         var mins = function(){
  103.                 mins.alloc = function(){
  104.                         cache[index] = cache[index] || {};
  105.                         return cache[index++];
  106.                 };
  107.                 var ret = me.apply(this, arguments);
  108.                 mins.alloc = null;
  109.                 index = 0;
  110.                 return ret;
  111.         }

  112.         mins.prototype = me.prototype;

  113.         return mins;
  114. }
  115. //----------------------------------------------------------------------------------------------------------
  116. var Test = function(){
  117.         var x = Test.alloc();
  118.         x.a = x.a || 0;
  119.         x.a++;
  120.         return x.a;
  121. }.$staticable();

  122. for(var i = 0; i < 10; i++)
  123.         alert(Test());
  124. //-----------------------------------------------------------------------------------------------------------
  125. Function.prototype.$protected = function(){
  126.         var me = this;
  127.        
  128.         var mins = function(){

  129.                 var p = me.getPrototypeObject();

  130.                 var ret = function(){}; //create a new object

  131.                 for(var each in mins.prototype)  //clone prototypes
  132.                 {
  133.                         if(mins.prototype[each] instanceof Function){
  134.                                 ret.prototype[each] = function(){
  135.                                         return mins.prototype[each].apply(p,arguments);        //call by p
  136.                                 }
  137.                                 p[each] = mins.prototype[each];
  138.                         }
  139.                         else{
  140.                                 p[each] = ret.prototype[each] = mins.prototype[each];
  141.                         }
  142.                 }
  143.                 me.apply(p,arguments);//clone a new object by me

  144.                 return new ret(); //return this object;
  145.         }
  146.         return mins;
  147. }
  148. //----------------------------------------------------------------------------------------------------------------
  149. //将一个类型的this域声明为全部私有
  150. var Test = function(x,y)
  151. {
  152.         this.x = x;
  153.         this.y = y;
  154. }.$protected();
  155. Test.prototype.getX = function(){
  156.         return this.x;
  157. }
  158. var t = new Test(5,10);
  159. alert(t.x);
  160. alert(t.getX());
  161. </script>
复制代码运行代码另存代码

[ 本帖最后由 月影 于 2008-4-12 20:20 编辑 ]

Rank: 2

升级  55.33%

注册时间
2004-8-20
威望
42
阅读权限
20
积分
133
帖子
21
精华
0
UID
15878
状态
当前离线
发表于 2008-4-11 22:42:34 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
没一点说明?

使用道具 举报

超级版主

5毛发一贴,千里不留行。

Rank: 8Rank: 8

注册时间
2007-2-27
威望
3584
阅读权限
150
积分
8408
帖子
3597
精华
12
UID
65747
状态
当前离线
发表于 2008-4-11 23:53:10 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
一贯如此啊 呵呵

居然都发到一起了......

使用道具 举报

超级版主

5毛发一贴,千里不留行。

Rank: 8Rank: 8

注册时间
2007-2-27
威望
3584
阅读权限
150
积分
8408
帖子
3597
精华
12
UID
65747
状态
当前离线
发表于 2008-4-12 00:21:28 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
Function.prototype.$bind=function(object)
{
    var tmp;
    with(object)
    {
        return eval('tmp=(' + this.toString() + ')');
    }
}

第一个 这样就行

还有 老大 你把题目改改啊 精华帖子题目不能是这个吧 TT

[ 本帖最后由 winter 于 2008-4-12 00:22 编辑 ]

使用道具 举报

Rank: 4

升级  76.8%

注册时间
2007-7-29
威望
358
阅读权限
50
积分
884
帖子
373
精华
0
UID
73645
状态
当前离线
发表于 2008-4-12 11:29:05 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
没看明白是啥东西,解释解释?

使用道具 举报

超级版主

5毛发一贴,千里不留行。

Rank: 8Rank: 8

注册时间
2007-2-27
威望
3584
阅读权限
150
积分
8408
帖子
3597
精华
12
UID
65747
状态
当前离线
发表于 2008-4-12 12:50:40 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
Function.prototype.$bind=function(object)
{
    var tmp;
    with(object)
    {
        return eval('tmp=(' + this.toString() + ')');
    }
}

我解释下这个吧 这是针对Function扩展的一个方法 将一个函数绑定到一个对象 在函数中 可以直接用变量访问相应的属性 比如 例子中的
var obj={a:1,b:2};
var f=function (){
    a=10;//这里修改了obj.a
    b=11;
}.$bind(obj);
f();
alert(obj.a);

不同于Prototype.js的bind 这个$bind改变了函数的作用域而非this

这个$bind可能有很多用处 包括实现设计模式templete method  实现像C++和C#那样成员函数直接用名称访问成员变量 还有一些私有之类的性质都可能用它来实现

使用道具 举报

Rank: 4

升级  16.4%

注册时间
2007-12-7
威望
290
阅读权限
50
积分
582
帖子
338
精华
0
UID
79982
状态
当前离线
发表于 2008-4-13 11:19:59 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
with和eval还有函数本身toString当直接函数............都是最奇怪的组合

使用道具 举报

Rank: 4

升级  61.4%

注册时间
2006-7-1
威望
375
阅读权限
50
积分
807
帖子
391
精华
0
UID
53867
状态
当前离线
发表于 2008-4-13 11:52:47 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
不太明白这段为什么要这样写。。。
var _interfaces = obj && obj.__interfaces__;
    if(_interfaces)
        for(var i = 0, len = _interfaces; i < len; i++){
            if(_interfafces == c)
                return true;
        }

使用道具 举报

Rank: 1

升级  62%

注册时间
2008-4-10
威望
15
阅读权限
10
积分
31
帖子
13
精华
0
UID
85191
状态
当前离线
发表于 2008-4-13 14:07:55 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
弄得我是越来越不懂javascript了

使用道具 举报

Rank: 3Rank: 3

升级  51%

注册时间
2006-9-10
威望
135
阅读权限
30
积分
353
帖子
135
精华
0
UID
56284
状态
当前离线
发表于 2008-4-13 14:34:48 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
var _interfaces = obj && obj.__interfaces__;
//上面相当于 if(!obj){
                           interfaces=obj;
                    }else{
                          interfaces=obj.__interfaces__;
                    }
    if(_interfaces)
        for(var i = 0, len = _interfaces; i < len; i++){
            if(_interfafces == c)
                return true;
        }

使用道具 举报

Rank: 4

升级  61.4%

注册时间
2006-7-1
威望
375
阅读权限
50
积分
807
帖子
391
精华
0
UID
53867
状态
当前离线
发表于 2008-4-13 19:29:01 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
var _interfaces = obj && obj.__interfaces__;
//上面相当于 if(!obj){
                           interfaces=obj;
                    }else{
                          interfaces=obj.__interfaces__;
                    }

&&的结果是布尔类型么?怎么会想你说的相当于呢?
还有 len = _interfaces这个是得到什么啊?不太理解,希望能够解释解释,多谢

使用道具 举报

超级版主

5毛发一贴,千里不留行。

Rank: 8Rank: 8

注册时间
2007-2-27
威望
3584
阅读权限
150
积分
8408
帖子
3597
精华
12
UID
65747
状态
当前离线
发表于 2008-4-13 20:18:01 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
[php]<script>
Function.prototype.$bind=function(object)
{
    var tmp;
    with(object)
    {
        return eval('tmp=(' + this.toString() + ')');
    }
}

function ClassA(){
    this.a=10;
    this.b=20;
    this.getA=function(){
        return a;//如果你喜欢在这里使用a 而不是this.a......
    }.$bind(this);
}

var objA=new ClassA();
alert(objA.getA());
objA.a=15;
alert(objA.getA());

</script>[/php]

使用道具 举报

Rank: 6Rank: 6

升级  69.45%

注册时间
2005-12-5
威望
982
阅读权限
70
积分
2389
帖子
917
精华
0
UID
43168
状态
当前离线
发表于 2008-4-13 20:37:15 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料 查看个人网站
还是改成
[php]
Function.prototype.$bind=function(object)
{
    with(object)
    {
        eval('var tmp=(' + this.toString() + ')');     
    }
    return tmp;
}
[/php]
看着顺眼
http://renjian.com

使用道具 举报

Rank: 2

升级  87.33%

注册时间
2005-7-1
威望
61
阅读权限
20
积分
181
帖子
47
精华
0
UID
32085
状态
当前离线
发表于 2008-4-14 10:03:00 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
  1. Function.prototype.$bind=function(object)
  2. {
  3.     with(object)
  4.     {
  5.         eval('var tmp=' + this.toString());     
  6.     }
  7.     return tmp;
  8. }
复制代码运行代码另存代码

使用道具 举报

Rank: 1

升级  62%

注册时间
2008-4-10
威望
15
阅读权限
10
积分
31
帖子
13
精华
0
UID
85191
状态
当前离线
发表于 2008-4-14 13:53:42 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
winter的功能,我还是宁可用下面的写法,免去对公用JS Function.prototype.$bind的依赖
  1. <script>
  2. Function.prototype.$bind=function(object)
  3. {
  4.     var tmp;
  5.     with(object)
  6.     {
  7.         return eval('tmp=(' + this.toString() + ')');
  8.     }
  9. }

  10. function ClassA(){
  11.     this.a=10;
  12.     this.b=20;
  13.     with(this){
  14.           this.getA=function(){
  15.                  return a;//如果你喜欢在这里使用a 而不是this.a......
  16.            }
  17.      }
  18. }

  19. var objA=new ClassA();
  20. alert(objA.getA());
  21. objA.a=15;
  22. alert(objA.getA());

  23. </script>
复制代码运行代码另存代码

使用道具 举报

Rank: 6Rank: 6

升级  13%

注册时间
2006-6-20
威望
344
阅读权限
70
积分
1260
帖子
351
精华
0
UID
53369
状态
当前离线
发表于 2008-4-14 23:58:00 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
没有看明白月老大的
var callback = function (fn) {
        return fn;
    }
这段在Function.prototype.$bind=function(object)中是用来做什么的:loveliness:
哪位知道的可以解释下不?
天下风云出我辈,一入江湖岁月催。
皇图霸业谈笑中,不胜人生一场醉。
提剑跨骑挥鬼雨,白骨如山鸟惊飞。
尘事如潮人如水,只叹江湖几人回。

使用道具 举报

Rank: 6Rank: 6

升级  43.95%

注册时间
2004-1-11
威望
1203
阅读权限
70
积分
1879
帖子
138
精华
4
UID
7929
状态
当前离线
发表于 2008-4-15 17:23:10 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
关于$bind()方法,winter的修改要好些,我看不出原来代码中声明一个callback()的理由。不过在winter的代码
中,tmp变量也可以省掉,方法可以是这样:

Function.prototype.$bind=function(object)
{
    with(object)
        return eval('[' + this.toString() + '][0]');
}

如果你觉得这里构造一个数组是浪费,那么可以更为复杂一点的代码:
Function.prototype.$bind=function(object)
{
    with(object)
        return eval('(' + this.toString() + ').prototype.constructor');
}

使用道具 举报

超级版主

5毛发一贴,千里不留行。

Rank: 8Rank: 8

注册时间
2007-2-27
威望
3584
阅读权限
150
积分
8408
帖子
3597
精华
12
UID
65747
状态
当前离线
发表于 2008-4-15 19:34:36 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
原帖由 Aiming 于 2008-4-15 17:23 发表
关于$bind()方法,winter的修改要好些,我看不出原来代码中声明一个callback()的理由。不过在winter的代码
中,tmp变量也可以省掉,方法可以是这样:

Function.prototype.$bind=function(object)
{
    w ...

Function.prototype.$bind=function(object)
{
    with(object)
        return eval('(' + this.toString() + ').prototype.constructor');
}
这个比较好 这个扩展原来就是我写的 直接
eval( this.toString() )了 结果发现IE不行......

顺便跟Aiming大牛探讨一下with的问题:lol

   with(object)
    {
        eval('var i=1;');
    }

关于这个的结果 你如何看呢

使用道具 举报

Rank: 6Rank: 6

升级  43.95%

注册时间
2004-1-11
威望
1203
阅读权限
70
积分
1879
帖子
138
精华
4
UID
7929
状态
当前离线
发表于 2008-4-15 19:46:31 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
楼上读书不认真,拖出去挠脚板挠到死~~

《JavaScript语言精髓与编程实践》"4.6.9.2 对象闭包带来的可见性效果",P246.

使用道具 举报

超级版主

5毛发一贴,千里不留行。

Rank: 8Rank: 8

注册时间
2007-2-27
威望
3584
阅读权限
150
积分
8408
帖子
3597
精华
12
UID
65747
状态
当前离线
发表于 2008-4-15 20:37:59 |显示全部楼层 |串个门|加好友|打招呼|发消息 |
查看详细资料
你的书我还没到手呢 呵呵 我是对这个ECMA262里面的解释比较疑惑 按照里面所说 with确确实实地改变了当前的scope chain
那var又是如何识别出scope chain上哪个是当前函数的scope呢?

使用道具 举报

您需要登录后才可以回帖 登录 | 加入无忧

Archiver|手机版|无忧脚本 ( 苏ICP备05080427号 )|值班电话:027-62300445  

GMT+8, 2012-2-7 21:24 , Processed in 0.065274 second(s), 14 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 1999-2011 无忧脚本

回顶部