`
cavenaghi
  • 浏览: 13983 次
  • 性别: Icon_minigender_1
  • 来自: 辽宁抚顺
最近访客 更多访客>>
社区版块
存档分类
最新评论

遇到prototyte一个很怪异的问题,大家一起讨论一下(已解决,总结一下)

阅读更多
function Test(url) {
	this.url = url;
	this.str = "want to save responseText";
}

Test.prototype.test = function () {
	alert(this.url); //可以访问到
	alert(this.str); //可以访问到
	var ajax = new Ajax.Request(
		this.url,{	
			method: "get",
			parameters: "time=" +  new Date().getTime(),
			onSuccess: function(req){
				alert(this.url); //可以访问到
				alert(this.str); //无法访问到
				//this.str = responseText; //期待的操作无法执行
			}
		}
	);
};

Event.observe(window, "load", pageLoad, false);
					
var url = "a action url";

function pageLoad(){
         var t = new Test(url);
	t.test();
}


在这里我创建一个页面,并导入了prototype,和上面这段代码.并注册页面的初始化事件
初始化事件只是创建一个我自定义的对象,并调用其中的一个方法

而当我调用这个方法的时候,

alert(this.url);
alert(this.str);
这些都可以正常访问

而在new Ajax.Request内部,却只能访问到this.url.无法访问this.str

===================================================================

上面是问题的阐述,在cozone_柯中和7thbyte的热心帮助下,终于找到了问题的解决方案

===================================================================

首先,在prototype中加入下列代码
var ClassUtils=Class.create();

ClassUtils.prototype={
        _ClassUtilsName:'ClassUtils',

        initialize:function(){
        },

        /**
         * 给类的每个方法注册一个对类对象的自我引用
         * @param reference 对类对象的引用
         */
        registerFuncSelfLink:function(reference){
                for (var n in reference) {
                var item = reference[n];                        
                if (item instanceof Function)
					item.$ = reference;
            }
        }
}


接着写我新的Test类
function Test(url) {
	this.url = url;
	this.str = "want to save responseText";
	new ClassUtils().registerFuncSelfLink(this);
}

Test.prototype.test = function () {
	var funcHolder=arguments.callee.$;
	alert(this.url); //可以访问到
	alert(this.str); //可以访问到
	var ajax = new Ajax.Request(
		this.url,{	
			method: "get",
			parameters: "time=" +  new Date().getTime(),
			onSuccess: function(req){
				alert(funcHolder.url); //可以访问到
				alert(funcHolder.str); //可以访问到
				funcHolder.str = responseText; //期待的操作可执行
			}
		}
	);
};

Event.observe(window, "load", pageLoad, false);
					
var url = "a action url";
vat t = new Test(url);//这次把作用域扩大一下

function pageLoad(){
	t.test();//可以了
}
function getTest(){
	alert(t.str);//可以随时察看一下,确实改变了,呵呵
}


======================================================================

至此再次对cozone_柯中和7thbyte的热心帮助表示感谢

======================================================================

6月21号增加:

以上的解决方案太依赖于prototyte了,其实在平时的应用中this指针也是经常遇到的问题

现在将这部分独立出来,也可以解决了
<script language="javascript">
function registerSelf(reference){
                for (var n in reference) {
                var item = reference[n];                        
                if (item instanceof Function)
					item.$ = reference;
            }
        }

var Book = function(){
	this.name = "book";
}

Book.prototype = {
	main : function(){
		alert(9);
	}
}

var Car = function(name){
	this.name = name;
	registerSelf(this)
}
Car.prototype = {
	getName : function(){
		var book = new Book();
		book.main();
		var self = arguments.callee.$; 
		alert(self.name)
		book.main = function(){
			alert(self.name);
		}
		book.main();
	}
}

function main(){
	var car = new Car("boya");
	car.getName();
}
</script>

<a href="#" onClick="main();">do</a>


======================================================================
分享到:
评论
17 楼 campaign 2007-07-31  
function Test(url) {   
    this.url = url;   
    this.str = "want to save responseText";   
}   
  
Test.prototype.test = function () {   
    alert(this.url); //可以访问到   
    alert(this.str); //可以访问到   
   new Ajax.Request(   
        this.url,{     
            method: "get",   
            parameters: "time=" +  new Date().getTime(),   
            onSuccess: function(req){   
                alert(this.url); //可以访问到   
                alert(this.str); //无法访问到   
                //this.str = responseText; //期待的操作无法执行   
            }.bind(this)
           );   
};   
  
Event.observe(window, "load", pageLoad, false);   
                       
var url = "a action url";   
  
function pageLoad(){   
         var t = new Test(url);   
    t.test();   
}   


ok 了可以访问了,干吗说的那么复杂,不理解
16 楼 笨笨狗 2007-07-31  
其实,最简单的办法,还是把回调函数提取出来,作为对象的一个实例方法,然后用Prototype提供的bind方法来把this指针绑定到需要的对象上,具体的可以参看我以前写过的一篇文章,注意看中间那一段提到的“ Prototype为Function对象扩展了一个bind方法和bindAsEventListener方法,可以很方便的将函数上下文(this)切换为别的对象……”<br/>
<br/>
<a href='http://scriptfans.iteye.com/blog/80298'> AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(中)</a><br/>
<br/>
这样不需要任何hack就能达到目的,何乐而不为呢?
15 楼 cdmar79 2007-07-30  
function handler(req){  
    alert(this.url);     
    alert(this.str);     


function handler(req){  
    alert(req.url);     
    alert(req.str);     

可以吗?
14 楼 superwen 2007-06-21  
cozone_柯中 写道
7thbyte 写道
搜索到了,相当好的解决方法

原文见:
Prototype.AjaxRequest的调用堆栈重写问题

对于这个帖子讨论的代码,可以这样修改

先在prototype.js的基础上实现一个ClassUtils类,定义如下方法

var ClassUtils=Class.create();
ClassUtils.prototype={
        _ClassUtilsName:'ClassUtils',
        initialize:function(){
        },
        /**
         * 给类的每个方法注册一个对类对象的自我引用
         * @param reference 对类对象的引用
         */
        registerFuncSelfLink:function(reference){
                for (var n in reference) {
                var item = reference[n];                        
                if (item instanceof Function) 
                                item.$ = reference;
            }
        }
}


然后此帖中的程序原来的代码改为:

function Test(url) {  
    this.url = url;  
    this.str = "responseText";
	new ClassUtils().registerFuncSelfLink(this);
}
  
Test.prototype = new Object();  
  
Test.prototype.test = function (tobj) {  
    //alert(tobj.url);  
    //alert(tobj.str);
    var funcHolder=arguments.callee.$;
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete:function(req){
                alert(funcHolder.url);  
                alert(funcHolder.str);
                funcHolder.str=req.responseText;
            }
        }   
    ); 
};


就没有什么问题了,我已经测试过


这个方法还是挺不错的


很强了.赞一个先.
13 楼 hozaka 2007-04-03  
this 指针指向的对象不一样,在 Test 类里 this 指向 test 类的实例,而 onSuccess 则是用 prototype 的 bind 绑在 ajax.request 类的实例,变量的作用域不同,因此不能访问
12 楼 cozone_柯中 2007-04-02  
7thbyte 写道
搜索到了,相当好的解决方法

原文见:
Prototype.AjaxRequest的调用堆栈重写问题

对于这个帖子讨论的代码,可以这样修改

先在prototype.js的基础上实现一个ClassUtils类,定义如下方法

var ClassUtils=Class.create();
ClassUtils.prototype={
        _ClassUtilsName:'ClassUtils',
        initialize:function(){
        },
        /**
         * 给类的每个方法注册一个对类对象的自我引用
         * @param reference 对类对象的引用
         */
        registerFuncSelfLink:function(reference){
                for (var n in reference) {
                var item = reference[n];                        
                if (item instanceof Function) 
                                item.$ = reference;
            }
        }
}


然后此帖中的程序原来的代码改为:

function Test(url) {  
    this.url = url;  
    this.str = "responseText";
	new ClassUtils().registerFuncSelfLink(this);
}
  
Test.prototype = new Object();  
  
Test.prototype.test = function (tobj) {  
    //alert(tobj.url);  
    //alert(tobj.str);
    var funcHolder=arguments.callee.$;
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete:function(req){
                alert(funcHolder.url);  
                alert(funcHolder.str);
                funcHolder.str=req.responseText;
            }
        }   
    ); 
};


就没有什么问题了,我已经测试过


这个方法还是挺不错的
11 楼 cavenaghi 2007-04-02  
先谢谢了,其实我只是想把异步读取来的数据,和一些操作,都封装到一个类里来完成,可刚写了一点就遇到了这个问题
10 楼 7thbyte 2007-04-02  
搜索到了,相当好的解决方法

原文见:
Prototype.AjaxRequest的调用堆栈重写问题

对于这个帖子讨论的代码,可以这样修改

先在prototype.js的基础上实现一个ClassUtils类,定义如下方法

var ClassUtils=Class.create();
ClassUtils.prototype={
        _ClassUtilsName:'ClassUtils',
        initialize:function(){
        },
        /**
         * 给类的每个方法注册一个对类对象的自我引用
         * @param reference 对类对象的引用
         */
        registerFuncSelfLink:function(reference){
                for (var n in reference) {
                var item = reference[n];                        
                if (item instanceof Function) 
                                item.$ = reference;
            }
        }
}


然后此帖中的程序原来的代码改为:

function Test(url) {  
    this.url = url;  
    this.str = "responseText";
	new ClassUtils().registerFuncSelfLink(this);
}
  
Test.prototype = new Object();  
  
Test.prototype.test = function (tobj) {  
    //alert(tobj.url);  
    //alert(tobj.str);
    var funcHolder=arguments.callee.$;
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete:function(req){
                alert(funcHolder.url);  
                alert(funcHolder.str);
                funcHolder.str=req.responseText;
            }
        }   
    ); 
};


就没有什么问题了,我已经测试过
9 楼 7thbyte 2007-04-02  
暂时想了一个不是很好的解决方法,应该能满足需求,不过写法不漂亮

给test方法给一个参数,而不是直接取this

Test.prototype.test = function (tobj) {  
    //alert(tobj.url);  
    //alert(tobj.str);  
    var ajax = new Ajax.Request(  
        tobj.url,{    
            method: "post",  
            parameters: "time=" +  new Date().getTime(),  
            onComplete: function(req){  
                alert(tobj.url);  
                alert(tobj.str);
                tobj.str=req.responseText;
            }  
        }  
    );  
}; 


使用test的时候像这样

	t.test(t);


简单分析了下
prototype.js里面的Ajax.Request类的options参数里的
onXXX系列在对象构造时的处理都是用它自定义的Function.bind()方法去绑定
过程中可能出现一些未知问题,所以this引用的指向有变化
所以原来的写法访问不到
8 楼 cavenaghi 2007-04-02  
cozone_柯中 写道
7thbyte 写道
刚才我弄错了,sorry

按我的理解 楼主的代码就相当于
Test.prototype.test = function () {   
    alert(this.url);   
    alert(this.str);   
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete: handler
        }   
    );   
};

function handler(req){
    alert(this.url);   
    alert(this.str);   
}


两个都访问不到应该是正常的

事实上就连url也访问不到
能alert出来是因为楼主的程序25行把url定义为全局变量了,两个变量名重复,假象


Ajax.Request 里面有个url属性.是可以正常访问到的


其实我的代码就是这样写的,我是想把读到的responseText保存到this.str里,但我发现在handler里读不到this.str,更谈不上赋值了!
大家帮我看看,怎么样能访问到this.str,并且将responseText的值赋给它
7 楼 7thbyte 2007-04-02  
cozone_柯中 写道
7thbyte 写道
刚才我弄错了,sorry

按我的理解 楼主的代码就相当于
Test.prototype.test = function () {   
    alert(this.url);   
    alert(this.str);   
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete: handler
        }   
    );   
};

function handler(req){
    alert(this.url);   
    alert(this.str);   
}


两个都访问不到应该是正常的

事实上就连url也访问不到
能alert出来是因为楼主的程序25行把url定义为全局变量了,两个变量名重复,假象


Ajax.Request 里面有个url属性.是可以正常访问到的


handler里面的此this.url并不是Ajax.Request里的url

实验一下,把
var url = "a action url";  
   
function pageLoad(){  
     var t = new Test(url);  
     t.test();  
}


全局变量去了,改成

function pageLoad(){  
     var t = new Test("a action url");  
     t.test();  
}


最后的两个alert结果都是undefined
6 楼 cozone_柯中 2007-04-02  
7thbyte 写道
刚才我弄错了,sorry

按我的理解 楼主的代码就相当于
Test.prototype.test = function () {   
    alert(this.url);   
    alert(this.str);   
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete: handler
        }   
    );   
};

function handler(req){
    alert(this.url);   
    alert(this.str);   
}


两个都访问不到应该是正常的

事实上就连url也访问不到
能alert出来是因为楼主的程序25行把url定义为全局变量了,两个变量名重复,假象


Ajax.Request 里面有个url属性.是可以正常访问到的
5 楼 7thbyte 2007-04-02  
刚才我弄错了,sorry

按我的理解 楼主的代码就相当于
Test.prototype.test = function () {   
    alert(this.url);   
    alert(this.str);   
    var ajax = new Ajax.Request(   
        this.url,{     
            method: "post",   
            parameters: "time=" +  new Date().getTime(),   
            onComplete: handler
        }   
    );   
};

function handler(req){
    alert(this.url);   
    alert(this.str);   
}


两个都访问不到应该是正常的

事实上就连url也访问不到
能alert出来是因为楼主的程序25行把url定义为全局变量了,两个变量名重复,假象
4 楼 shiweiwei97 2007-04-02  
不太会用这个标签,不能嵌套吗?

Test.prototype.test = function () {  
    alert(this.url);  
    alert(this.str);
	var url = this.url;
	var str = this.str;
    var ajax = new Ajax.Request(  
        this.url,{    
            method: "post",  
            parameters: "time=" +  new Date().getTime(),  
            onSuccess: function(req){  
                alert(url);  
                alert(str);  
            }  
        }  
    );  
};  
3 楼 shiweiwei97 2007-04-02  
试试这样
Test.prototype.test = function () {  
    alert(this.url);  
    alert(this.str);
	[b]var url = this.url;
	var str = this.str;
[/b]    var ajax = new Ajax.Request(  
        this.url,{    
            method: "post",  
            parameters: "time=" +  new Date().getTime(),  
            onSuccess: function(req){  
 [b]               alert(url);  
                alert(str);  
[/b]            }  
        }  
    );  
};  
2 楼 cavenaghi 2007-04-02  
怎么样能访问到Test里的this.str?
1 楼 cozone_柯中 2007-04-02  
引用


var ajax = new Ajax.Request(  
        this.url,{    
            method: "post",  
            parameters: "time=" +  new Date().getTime(),  
            onSuccess: function(req){  
                alert(this.url);  
                alert(this.str);  
            }  
        }  
    );  



作用域的问题,你在里面访问的 this.url 是 这个Ajax.Request对象的属性 并不是 Test的

相关推荐

    多智能体一致性仿真 简单的多智能体一致性性仿真图,包含状态轨迹图和控制输入图 程序简单,所以便宜,但是有注释,都能看懂,适合初学者

    多智能体一致性仿真 简单的多智能体一致性性仿真图,包含状态轨迹图和控制输入图。 程序简单,所以便宜,但是有注释,都能看懂,适合初学者。

    小程序项目-基于微信小程序的微信小程序租房平台(包括源码,数据库,教程).zip

    Java小程序项目源码,该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:小程序 后端框架:SSM/SpringBoot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven

    模糊PID控制器的C语言实现.zip

    模糊PID控制器的C语言实现

    电子科技大学图书馆微信小程序_中国电子科技大学.zip

    电子科技大学图书馆微信小程序_中国电子科技大学

    武汉市新版劳动合同.doc

    武汉市新版劳动合同

    用于微信小程序的ProtoBuffer库.zip

    用于微信小程序的ProtoBuffer库

    WINCC 用VBS写MYSQL动作说明

    WINCC 用VBS写MYSQL动作说明

    039智能微电网PSO优化算法,比较全,推荐下载。matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    Stentiford 细化算法Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    含高比例分布式光伏的配电网集群电压协调控制 摘要:代码主要做的是基于网络划分的双层电压控制策略,通过优化光伏变流器的有功和无功输出功率实现光伏发电损失和线路有功损耗最小,在集群划分基础上,研究包含群内

    含高比例分布式光伏的配电网集群电压协调控制 摘要:代码主要做的是基于网络划分的双层电压控制策略,通过优化光伏变流器的有功和无功输出功率实现光伏发电损失和线路有功损耗最小,在集群划分基础上,研究包含群内自治优化和群间分布式协调的双层电压控制策略,集群自治优化控制通过交替更新群内最优解和平衡节点电压实现群内电压的实时快速控制。 长时间尺度的群间分布式协调控制基于交方向乘子法,通过相邻集群的有限边界数据交实现对分布式光伏输出功率的全局优化控制。 复现结果非常良好,结果图展示如下:

    springboot170图书电子商务网站的设计与实现.zip

    springboot170图书电子商务网站的设计与实现,含有完整的源码和报告文档

    客车驾驶员劳动合同.doc

    客车驾驶员劳动合同

    Bernsen 阈值方法的实现。.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    springboot164党员教育和管理系统.zip

    springboot164党员教育和管理系统,含有完整的源码和报告文档

    小区团购-JAVA-基于springboot小区团购管理设计与实现(毕业论文)

    以下是小区团购系统的功能描述,旨在为小区居民提供便捷的团购服务,以便于集中采购、节省开支和提高生活质量。 小区团购系统功能描述 1. 用户角色 管理员 商家 居民 2. 功能描述 管理员功能 用户管理 管理居民和商家的注册、审核、修改和删除。 设置不同用户的权限,确保系统安全性。 团购管理 创建、编辑和删除团购活动,包括商品信息、价格、起订量及截止时间。 审核商家提交的团购活动,确保商品质量和服务可靠性。 订单管理 监控所有团购订单的状态,包括未支付、已支付、配送中和完成等。 支持订单查询、修改和取消处理。 数据统计与分析 生成团购活动的销售报表和参与情况统计,帮助评估活动效果。 分析用户购买行为,以优化后续团购活动。 优惠活动管理 设置和管理促销活动(如满减、折扣、买赠等),吸引更多居民参与团购。 跟踪活动效果,调整策略以提升销售额。 商家功能 商家注册与管理 注册并创建商家账户,填写基本信息(如店铺名称、联系方式、地址等)。 提交商品信息,设置价格和库存,管理团购活动。 团购活动发布 创建新的团购活动,上传商品图片,详细描述和定价。 设置活动开始和结束时间,定义团购

    Multisim仿真TL494BUCK闭环,稳定输出5v,带软启动 电流限制为0.14A电流超过限制电压下降,为电流保护 软启动由4脚控制,示波器可看到输出 需要用Multisim14才能打开

    Multisim仿真TL494BUCK闭环,稳定输出5v,带软启动。 电流限制为0.14A电流超过限制电压下降,为电流保护。 软启动由4脚控制,示波器可看到输出。 需要用Multisim14才能打开。

    【热力学】基于matlab烤箱中烤面包的非稳态传热过程仿真【含Matlab源码 10961期】.zip

    Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    springboot161基于springboot的公交线路查询系统.zip

    springboot161基于springboot的公交线路查询系统,含有完整的源码和报告文档

    微信小程序云增强SDK_xpmjs.zip

    微信小程序云增强SDK_xpmjs

    matlab实现飞翼无人机鲁棒控制-飞翼无人机-鲁棒控制-matlab

    内容概要:本文详细介绍了飞翼无人机的鲁棒控制原理及其在Matlab中的实现方法。飞翼无人机因构型特殊而面临诸多不确定性,导致飞行过程复杂。文中首先讨论了飞翼无人机鲁棒控制的概念和意义,重点描述了鲁棒控制‘最坏情况设计’的思想,以确保在各种环境下系统的稳定性。然后阐述了鲁棒控制的具体流程,涉及系统建模、不确定性分析、鲁棒控制器(如H∞、滑模、自适应控制)设计、仿真实验及硬件实验,最后提供了完整的Matlab源码与运行指南,并展示了开环和闭环系统的响应对比结果,证明所设计的鲁棒控制器的有效性。文章末尾对未来的研究方向提出了展望。 适合人群:从事航空航天工程的专业人士,尤其是专注于无人机构型控制领域的研究人员;以及有一定自动化控制理论基础并对Matlab仿真感兴趣的学习者。 使用场景及目标:本篇文章主要面向希望通过理论研究提升无人机控制能力的学者或从业者,帮助他们掌握从建模到验证一套完整的鲁棒控制方法论,并为解决实际工程问题奠定坚实理论基础。此外,对于学生来说,这是一个很好的案例教学材料。 其他说明:提供的仿真代码不仅可用于科研学习也可以作为工业项目中初步设计的一部分参考素材。

Global site tag (gtag.js) - Google Analytics