标题: [原创] 有意思的function扩展……
月影
超级版主
Rank: 8Rank: 8



UID 24714
精华 9
积分 4243
帖子 1553
威望 1918
阅读权限 150
注册 2005-3-9
状态 离线
 
发表于 2008-4-11 21:58  资料  个人空间  主页 短消息  加为好友  QQ
有意思的function扩展……




<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.objInstanceOf = function(objc){
    if(
typeof(c) == "string")
        return 
typeof(obj) == c;
    if(
obj instanceof || c.__templete__ && obj instanceof c.__templete__)
        return 
true;
    var 
_interfaces obj && obj.__interfaces__;
    if(
_interfaces)
        for(var 
0len _interfacesleni++){
            if(
_interfafces[i] == c)
                return 
true;
        }
    return 
false;
};

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

Function.
prototype.getPrototypeObject = function(){
    var 
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(thisarguments);
        return 
ret;
    }

    
ins.prototype p.getPrototypeObject();
    return 
ins;
};
//--------------------------------------------------------------------------------------------------------
function B(){};
var 
= function(){
    
alert($super);
}.
$pextends(B);
var 
= 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 
0len _args.lengthleni++)
        {
            if(!
G.objInstanceOf(arguments[i],_args[i])){
                    throw new 
TypeError("函数的参数类型不匹配,位置:"+(i+1));
            }
        }
        return 
me.apply(thisarguments);
    }
    
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;
    
this.y;
}.
$verify("number","number");
Class3.prototype.dist2 = function(){return this.x*this.this.y*this.y};
var 
= 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(thisarguments);
        
mins.alloc null;
        
index 0;
        return 
ret;
    }

    
mins.prototype me.prototype;

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

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

        var 
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;
    
this.y;
}.
$protected();
Test.prototype.getX = function(){
    return 
this.x;
}
var 
= new Test(5,10);
alert(t.x);
alert(t.getX());
</script> 




   提示:您可以先修改部分代码再运行

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

顶部
gsoft
爬虫
Rank: 2



UID 15878
精华 0
积分 133
帖子 21
威望 42
阅读权限 20
注册 2004-8-20
状态 离线
 
发表于 2008-4-11 22:42  资料  个人空间  短消息  加为好友 
没一点说明?

顶部
winter
超级版主
Rank: 8Rank: 8
5毛发一贴,千里不留行。


UID 65747
精华 11
积分 7582
帖子 3353
威望 3335
阅读权限 150
注册 2007-2-27
状态 离线
 
发表于 2008-4-11 23:53  资料  个人空间  短消息  加为好友 
一贯如此啊 呵呵

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





顶部
winter
超级版主
Rank: 8Rank: 8
5毛发一贴,千里不留行。


UID 65747
精华 11
积分 7582
帖子 3353
威望 3335
阅读权限 150
注册 2007-2-27
状态 离线
 
发表于 2008-4-12 00:21  资料  个人空间  短消息  加为好友 
Function.prototype.$bind=function(object)
{
    var tmp;
    with(object)
    {
        return eval('tmp=(' + this.toString() + ')');
    }
}

第一个 这样就行

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

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





顶部
mypda07
大恐龙
Rank: 4



UID 73645
精华 0
积分 757
帖子 326
威望 313
阅读权限 50
注册 2007-7-29
状态 离线
 
发表于 2008-4-12 11:29  资料  个人空间  短消息  加为好友 
没看明白是啥东西,解释解释?

顶部
winter
超级版主
Rank: 8Rank: 8
5毛发一贴,千里不留行。


UID 65747
精华 11
积分 7582
帖子 3353
威望 3335
阅读权限 150
注册 2007-2-27
状态 离线
 
发表于 2008-4-12 12:50  资料  个人空间  短消息  加为好友 
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#那样成员函数直接用名称访问成员变量 还有一些私有之类的性质都可能用它来实现





顶部
afcn0
大恐龙
Rank: 4



UID 79982
精华 0
积分 582
帖子 337
威望 290
阅读权限 50
注册 2007-12-7
状态 离线
 
发表于 2008-4-13 11:19  资料  个人空间  短消息  加为好友 
with和eval还有函数本身toString当直接函数............都是最奇怪的组合

顶部
PaulLeder
大恐龙
Rank: 4



UID 53867
精华 0
积分 791
帖子 382
威望 368
阅读权限 50
注册 2006-7-1
状态 离线
 
发表于 2008-4-13 11:52  资料  个人空间  短消息  加为好友 
不太明白这段为什么要这样写。。。
var _interfaces = obj && obj.__interfaces__;
    if(_interfaces)
        for(var i = 0, len = _interfaces; i < len; i++){
            if(_interfafces[i] == c)
                return true;
        }

顶部
李上劲
小虫
Rank: 1



UID 85191
精华 0
积分 31
帖子 13
威望 15
阅读权限 10
注册 2008-4-10
状态 离线
 
发表于 2008-4-13 14:07  资料  个人空间  短消息  加为好友 
弄得我是越来越不懂javascript了

顶部
jianglang
小恐龙
Rank: 3Rank: 3



UID 56284
精华 0
积分 352
帖子 135
威望 135
阅读权限 30
注册 2006-9-10
状态 离线
 
发表于 2008-4-13 14:34  资料  个人空间  短消息  加为好友 
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;
        }

顶部
PaulLeder
大恐龙
Rank: 4



UID 53867
精华 0
积分 791
帖子 382
威望 368
阅读权限 50
注册 2006-7-1
状态 离线
 
发表于 2008-4-13 19:29  资料  个人空间  短消息  加为好友 
var _interfaces = obj && obj.__interfaces__;
//上面相当于 if(!obj){
                           interfaces=obj;
                    }else{
                          interfaces=obj.__interfaces__;
                    }

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

顶部
winter
超级版主
Rank: 8Rank: 8
5毛发一贴,千里不留行。


UID 65747
精华 11
积分 7582
帖子 3353
威望 3335
阅读权限 150
注册 2007-2-27
状态 离线
 
发表于 2008-4-13 20:18  资料  个人空间  短消息  加为好友 



<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> 







顶部
prodigynonsense
霸王龙
Rank: 6Rank: 6


UID 43168
精华 0
积分 2389
帖子 917
威望 982
阅读权限 70
注册 2005-12-5
来自 浙江余姚
状态 离线
 
发表于 2008-4-13 20:37  资料  个人空间  主页 短消息  加为好友 
还是改成


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



看着顺眼





http://renjian.com
顶部
ctfwren
爬虫
Rank: 2



UID 32085
精华 0
积分 179
帖子 46
威望 60
阅读权限 20
注册 2005-7-1
状态 离线
 
发表于 2008-4-14 10:03  资料  个人空间  短消息  加为好友 


   提示:您可以先修改部分代码再运行


顶部
李上劲
小虫
Rank: 1



UID 85191
精华 0
积分 31
帖子 13
威望 15
阅读权限 10
注册 2008-4-10
状态 离线
 
发表于 2008-4-14 13:53  资料  个人空间  短消息  加为好友 
winter的功能,我还是宁可用下面的写法,免去对公用JS Function.prototype.$bind的依赖

   提示:您可以先修改部分代码再运行


顶部
tonghu008 (Libra)
霸王龙
Rank: 6Rank: 6


UID 53369
精华 0
积分 1199
帖子 345
威望 339
阅读权限 70
注册 2006-6-20
状态 离线
 
发表于 2008-4-14 23:58  资料  个人空间  短消息  加为好友 
没有看明白月老大的
var callback = function (fn) {
        return fn;
    }
这段在Function.prototype.$bind=function(object)中是用来做什么的
哪位知道的可以解释下不?





天下风云出我辈,一入江湖岁月催。
皇图霸业谈笑中,不胜人生一场醉。
提剑跨骑挥鬼雨,白骨如山鸟惊飞。
尘事如潮人如水,只叹江湖几人回。
顶部
Aiming
霸王龙
Rank: 6Rank: 6



UID 7929
精华 3
积分 1419
帖子 130
威望 820
阅读权限 70
注册 2004-1-11
状态 离线
 
发表于 2008-4-15 17:23  资料  个人空间  短消息  加为好友 
关于$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');
}

顶部
winter
超级版主
Rank: 8Rank: 8
5毛发一贴,千里不留行。


UID 65747
精华 11
积分 7582
帖子 3353
威望 3335
阅读权限 150
注册 2007-2-27
状态 离线
 
发表于 2008-4-15 19:34  资料  个人空间  短消息  加为好友 


QUOTE:
原帖由 [i]Aiming[/i] 于 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的问题

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

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





顶部
Aiming
霸王龙
Rank: 6Rank: 6



UID 7929
精华 3
积分 1419
帖子 130
威望 820
阅读权限 70
注册 2004-1-11
状态 离线
 
发表于 2008-4-15 19:46  资料  个人空间  短消息  加为好友 
楼上读书不认真,拖出去挠脚板挠到死~~

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

顶部
winter
超级版主
Rank: 8Rank: 8
5毛发一贴,千里不留行。


UID 65747
精华 11
积分 7582
帖子 3353
威望 3335
阅读权限 150
注册 2007-2-27
状态 离线
 
发表于 2008-4-15 20:37  资料  个人空间  短消息  加为好友 
你的书我还没到手呢 呵呵 我是对这个ECMA262里面的解释比较疑惑 按照里面所说 with确确实实地改变了当前的scope chain
那var又是如何识别出scope chain上哪个是当前函数的scope呢?





顶部
 



当前时区 GMT+8, 现在时间是 2010-7-31 04:35
苏ICP备05080427号

Powered by Discuz! 5.5.0  © 2001-2007 51JS.COM
Processed in 0.502290 second(s), 8 queries , Gzip enabled

清除 Cookies - 联系我们 - 无忧脚本 - Archiver