Akawa

ETY001的博客

1、背景
Javascript中的回调函数,相信大家都不陌生,最明显的例子是做Ajax请求时,提供的回调函数,
实际上DOM节点的事件处理方法(onclick,ondblclick等)也是回调函数。

在使用DWR的时候,回调函数可以作为第一个或者最后一个参数出现,如:

function callBack(result){
}
myDwrService.doSomething(param1,param2,callBack);//DWR的推荐方式
//或者
myDwrService.doSomething(callBack,param1,param2);

2、问题描述
最近在使用Dojo+Dwr的时候,碰到一个问题:
如果回调函数是属于某个对象(记为obj1)的方法,等到DWR执行该回调函数的时候,
上下文却不是obj1。
表现的现象就是在回调函数中访问obj1的任何属性都是undefined。

版本:Dojo1.3.1和dwr2

3、模拟问题的代码
下面的测试代码可以模拟这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html>
<head>
<script>
var context="全局";
var testObj={
context:"初始",
callback:function (str){//回调函数
alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str);
}
};//创建一个对象,作为测试回调函数的上下文
testObj.context="已设置";

function testCall(){
callMethod(testObj.callback);
callObjMethod(testObj,testObj.callback);
}
function callObjMethod(obj,method){
method.call(obj,"指定显式对象上下文回调");
}
function callMethod(method){
method("通过默认上下文回调");
}
</script>
</head>
<body>
<a href="javascript:void(0)" onclick="testCall()">调用测试</a>
</body>
</html>

在testCall方法中,我用了两种方式回调“testObj.callback”方法:
第一种方式:method(“通过默认上下文回调”);
没有指定上下文,我们发现回调函数内部访问context的值是全局变量的值,
这说明,执行该方法的默认上下文是全局上下文。

第二种方式:method.call(obj,”指定显式对象上下文回调”);
指定obj为method执行的上下文,就能够访问到对象内部的context。

4、研究DWR
因为06年使用DOJO+DWR(1.0)的时候,已经遇到过这个问题,当时没做太多功课,直接改了dwr的源代码。

现在用dwr2,于是想先看看DWR是不是对这个问题有新的处理方式,
将dwr.jar中的engine.js拿出来,查看了有关回调的相关代码(_remoteHandleCallback_execute),
发现对回调的处理方式似乎比1.0更简单,没办法将对象和方法一起传过去。

5、做进一步的研究
因为这次DWR在项目中的使用太广泛,而且我相信这样的需求应该是可以满足的,于是没有立刻修改源码,

首先,在Google上搜Dojo+dwr,没有查到什么结论,可能Dojo的用户不是太多。

于是又搜”javascript callback object context“,得到一篇文章专门介绍java回调函数的文章:
http://bitstructures.com/2007/11/javascript-method-callbacks
最重要的一句话:

When a function is called as a method on an object (obj.alertVal()),
"this" is bound to the object that it is called on (obj).
And when a function is called without an object (func()),
"this" is bound to the JavaScript global object (window in web browsers.)

这篇文章也提供了解决方案,就是使用Closure和匿名方法,
javascript中,在function内部创建一个function的时候,会自动创建一个closure,
而这个closure就能记住对应的function创建时的上下文。

所以,如果这样:

1
2
3
var closureFunc=function(){
testObj.callback();
}

那么无论在什么地方,直接调用closureFunc()和调用testObj.callback()是等价的。

详情参见上面提到的文章:http://bitstructures.com/2007/11/javascript-method-callbacks。

6、改进模拟代码
在模拟代码中,我们再增加一种回调方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<html>
<head>
<script>
var context="全局";
var testObj={
context:"初始",
callback:function (str){//回调函数
alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str);
}
};//创建一个对象,作为测试回调函数的上下文
testObj.context="已设置";

function testCall(){
callMethod(testObj.callback);
callWithClosure(function(param){testObj.callback(param);});
callObjMethod(testObj,testObj.callback);
}
function callObjMethod(obj,method){
method.call(obj,"指定显式对象上下文回调");
}
function callMethod(method){
method("通过默认上下文回调");
}
function callWithClosure(method){
method("通过Closure保持上下文回调");
}
</script>
</head>
<body>
<a href="javascript:void(0)" onclick="testCall()">调用测试</a>
</body>
</html>

测试以上代码,我们可以发现,通过Closure和通过显示指定对象得到的效果一致。

由于我在办理域名转移时遇到了很垃圾的服务商,导致了我的域名转移过程中域名停止解析长达将近两周。现在网站的域名转移已经进入最后的接入商手续办理阶段,等全部结束此次域名转移后,我将详细向大家讲述一下这次的经历,到时候希望大家看后以后能够注意一下。

另外各位使用@domyself.me的各个朋友真是很抱歉,由于我个人之前没有备份过DNS配置信息,另加腾讯的域名邮箱功能的不完善,不得不迫使我把当前的域名邮箱注销掉,然后在24小时之后重新开通。对于近两周@domyself.me域名邮箱的不能使用给大家抱个歉,希望没有耽误大家什么重要的事情!

今天闲着的时候手绘的一些表情,现在拿出来跟大家分享一下,希望各位伸手党手下留情能留着我的水印哈,谢谢啦!

今天花钱买了个教训。之前一直都是无视各种地摊的U盘,知道便宜无好货。最近在一次机房上机后,把我原来的4GB的联想原装U盘给弄丢了,没办法只能去新买一块了。由于知道地摊货不好,即使是门面店也不会有好货,但是因为急用,于是就从学校边上的爱书人店里买了一块SONY 4GB的U盘。

当时买的时候,女老板一直在说这里进货都是正品,各种理由来阐明自己进的货是正品,我也没多少工夫和她磨这个嘴皮子,速战速决就回宿舍了。

回宿舍后就发现了问题。由于我的电脑是使用的win7+ylmf os 3.0的双系统,平时都是在ylmf os下工作,所以回宿舍测试U盘的时候,就是在ylmf下进行的,结果ubuntu不识别……杯具了,换到win7下面,从百度上搜了一个检测软件Chip Genius(芯片精灵),检测了一下,显示内容如下:

我的天,晕掉了,这个山寨u盘,我又从网上搜到了一条信息,sony人家只有记忆棒,从来没有出过u盘……

于是继续百度,看看能不能解决ubuntu不识别的问题。结果很好,有人也和我一样,并且已经搞定了。思路基本上和我想的是一样的,不过他成功了,那就不需要我再探索了,只要按照他说的做做看就OK了。方法在这里:http://wenku.baidu.com/view/178d7913a2161479171128b1.html

杯具的是通过量产工具低格后,4G变1G了…… 鸭梨

还是希望各位以后买U盘的时候能够去专卖店,比如说去联想专卖店买联想的U盘,还有就是真品U盘都有防伪码的,注意包装质量。

今天网站再一次搬家啦,并不是因为之前的服务器不好用,而是因为想上手个VPS玩玩,所以正好前一个8元/月的服务器空间马上到期,现在入手了一个便宜的VPS。

经过2个多小时的配置,服务器已经可以使用了,并且我还邪恶的下载了挂QQ软件,一口气挂了4个QQ在那上面。

现在的服务器的软件配置如下:

win2003+xampp+一个小ftp服务器软件
接下来,就要好好学习一下怎样配置和维护服务器了

整体来看52元/月的VPS速度对于我这样的一个小站完全可以接受,现在就是看看稳定性如何了。

如果大家感兴趣的话,可以来这里看看,http://vps.03host.com/page.aspx?c=referral&u;=12202

这几天一直憋着没写日记是有原因的,因为一直在开发ntalker插件(测试地址:999981.tk)。下面就说说开发的事情。

总体来说,对于此次的开发我不是很满意的,一共就需要写两个文件,加起来的代码量不足1000行,只是实现了最基本的聊天功能,并且其中70%是来自于ntalker提供的demo程序和ntalker提供的ucenterhome的插件,效率以及抗压能力太差了。主要是效率太低了,几乎每天都在马不停蹄的思考,阅读,编写,但是还是用了4天。本来以为3天的时间会很轻松完成任务的,但是预估错了……就现在这个状态,上社会上怎么能有竞争力呢?!

总结以下原因:

1、对于一些基本概念的理解还是不到位。

由于刚开始学C++,所以对于PHP的面向对象编程也不是很懂,这就导致了在阅读记事狗微博的源程序时耗费了很多时间,即使是现在对于一些概念的理解还是不够深入,比如说上节课C++老师刚重点强调的变量的作用域。

2、时间利用率不高。

工作期间开着QQ基本上就是个错误,即使自己隐身但是还是有很多的消息来影响你,因为貌似现在都知道我隐身了……所以说,以后再开发东西的时候,果断QQ离线!另外,在baidu未知知识的时候,总是被一些其他的信息所吸引,这个以后要注意!还有通宵并不总是明智的选择,当你没有思路的时候,又很困,那就没必要再通宵了,好好的去睡个觉。只有在你思路很清晰或者灵感来的时候,可以考虑通一下宵,借着热乎劲把东西写出来。

3、自我调节能力差。

遇到卡壳的问题的时候,不能一直在电脑前傻坐着,应该换个空间呆一会。

4、基础的一些类似算法,SQL等东西的掌握很不牢固,这条很第一条都差不多一个意思。之所以再写一编,就是因为这次这个原因对于我的触动真的是太大了!得好好反思和继续学习啊!

由于现在程序并不是很完善,我打算再完善一下后放出来插件程序供大家下载使用,还请各位有需要的朋友随时关注本博客~

如果时间不紧的话,我还打算把ntalker做到wordpress上来,这个先这么计划着吧~

调整两天后,进入新的压力测试!

今天在网上乱转的时候,发现了一个3美刀每月的便宜VPS。一直想试试VPS,看看是个什么效果,并且也想写个机器人放到VPS上运行运行看看,这次是有机会了,等这个空间到期后,我准备买一个试试。

他的具体配置如下:

磁盘空间20GB RAID10
内存128MB
突发内存256MB
月流量300GB
1个独立IP
SolumsVM控制面板

大家可以点击:这里去看看

今天这一天,我们的确是等了很久,可能从建波那一批提出要建自己的网站开始吧,我们就一直在为能有一个自己的网站而努力。今天就是这么一天,我们的梦想终于实现了。我现在不想说这个过程是多么的艰难,我只是想说点别的什么有用的东西。

这阵子我算是一直在跟班打杂。我想说因为我爱这里,因为我在这里投入了我大学的绝大多数精力,因为我把这里当作是自己的东西自己的家,所以我才如此的放不下,所以我才会过来跟班,所以我才会愿意协助09级的忙前忙后。

今天的发布会结束我也是思索了很多事情。比如说我们为什么进入社团,为什么进入学生会?我现在才算是找到社团和学生会的本质。学生会教给你的是为人处世的法则,而社团教给你的是如何实事求是的全身心的做事。学生会没有进过,我也不想多说,但是有一点是肯定的,学生会出来的人都很赶眼神,至少他们知道领导来视察应该礼貌一下。下面就说说我现在对于社团的理解。其实社团就是有点像企业的,你有能力你就发挥出来,没能力你就走人,你能拿出成绩来你就留下,拿不出成绩来你就走人,有时候的做事就是像企业这样没有情感的。但是有些时候,社团是需要情感的,因为毕竟不是企业,大家进入这个团队后,很快就会离开这个团队,到时候带走的除了曾经一起做过的成果外,无非就是在做这些事情的时候建立的深厚的友谊!如何把握这个度,则是一个团队领导人需要做的事情了。

社团如果想要发展好,需要均衡各种内部力量,这对于这个团队的领导层有很大的要求,这不是一个人所能做出来想出来的。就像今天的上线仪式发布会,这就是整个社团的事情,是整个社团的荣誉。在这个事情当中,每个人都相当于是一台战争机器的零件,然后一帮人通过一定的组织结构构成了一个战争机器来把眼前的所有困难击碎。而在这个过程中,只要有一个零件跟不上,那就成为了整个机器的短板,成为了敌人打击的软肋,然后被敌人打击后,除了这个零件被打击外,其他的零件一样跟着遭殃。这就是团队,这也是一个团队该怎样发展好,首先应该考虑的。作为团队一员,只有把这个地方的东西真正当作自己的东西的时候,这个地方所获得的荣誉你才有资格分享,只有把这个地方的东西真正当作自己的东西的时候,这个地方才会无时无刻的让你牵挂!

最后再说说这次的上线发布会。从今下午的整体来看,整个过程比较流畅,没有出现很大的纰漏,这一点我很欣慰,毕竟09级的团队再上一年后半年几乎一个学期被迫停止工作,缺少必要的磨合,另外也是这个团队第一次搞这样的大型晚会类型的项目,能做到今天的样子已经很满意了。我作为站长,也代表08级,非常的感谢每位成员的奉献与努力,尤其是让我感动的几个画面,一个是舞蹈排练人员的排练场面,一个是各种默默无闻工作在角落里的甘于寂寞的成员的画面。无论怎么说,你们的付出使得这次的发布会顺利的完成,各位,辛苦了!

但是,我觉得作为现在的管理层,09级的各位成员,你们应该利用这两天的休息的时间再回顾一下这次发布会,从一开始到最后的结束收尾,你们每个人哪里做的还不足,好好的用文字总结一下(我一直相信写东西,会使你自己更加能完善你自己的思想),这个总结对于你们来说很重要,对于团队来说也很重要(传到团队博客上),因为这些都是经验,因为这些都是文化的一部分。

也许现在可能还有成员因为兴奋或者因为在思考还没有入睡,但是我想说,各位尽快理顺思路平静下来吧,因为团队的挑战现在才刚刚开始,我们从去年到今年只活过来半口气,我们需要做的事情还有很多很多,我们需要付出更多的努力才能有所收获,各位,加油,拿出点实际行动来!!!

今天的C++实验课上的实验之一是调试并运行程序,然后分析结果。继续关于指针和数组的复习。通过该实验,我对于指针又有了更进一步的理解。下面我们就来看一下,对于指针的理解,都写在了程序的注释部分了。我自己的总结就是,看到指针时,先看看这是几维的,然后分清楚+1是对第几维做的,再然后看好*是对哪一部分进行降维操作的,最后看看是输出的地址还是值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream.h>
int a[][3]={1,2,3,4,5,6,7,8,9};
int *p[]={a[0],a[1],a[2]};
int **pp=p;
void main()
{
int (*s)[3]=a,*q=&a[0][0];
for(int i(1);i<3;i++)
for(int j(0);j<2;j++)
{
cout<<*(a[i]+j)<<','<<*(*(p+i)+j)<<','<<(*(pp+i))[j]<<',';
cout<<*(q+3*i+j)<<','<<*(*s+3*i+j)<<endl;
}

cout<<*s<<','<<s[0]<<endl;
}

/*
(1)运行结果分析
4,4,4,4,4
5,5,5,5,5
7,7,7,7,7
8,8,8,8,8
Press any key to continue
*(a[i]+j)表示第i+1+j行第一列元素
*(*(p+i)+j):p是二级指针,p+i表示第i行地址,也是二级指针,通过*降维,然后加j表示第i行第j+1列元素地址,再用*降维
(*(pp+i))[j]:(*(pp+i))的效果其实就是a[i],
*(q+3*i+j):q是一维指针,所以该式表示的是从q指向的元素向后移动3*i+j个元素
*(*s+3*i+j):s和p是一样的,*s表示的是一个一维的数组的首地址,即*s和q是等价的。

(3)
a[0]+1表示的是第一行第二列的元素的地址,因为a[0]是一个一维的指针,即a[0]表示的是从数组的第一个元素开始的一个一维数组的首地址
*(p+1)+1表示第二行第二列元素的地址,因为p是二维指针,p+1表示的是二维中的第一维加一,即p+1表示的是第二行元素,通过*进行降维后再加一即为第二列的元素地址
*(pp+1)[1]表示第二行第二列元素
q+3表示第四个元素的地址,即4的地址
*s+3表示第4个元素的地址

(4)
p是指针数组,s是指向数组的指针。p[]是一个数组空间的,只不过这个数组的每个空间是用来存储的地址的,而s是一个指针,指向的是一个数组空间。

*/

由于前几天的未知错误,导致博客中断了几天。重新开张后的博客,做了以下的改动:
1.安装“春菜”插件(插件安装搜索MP-Ukagaka即可),插件首页:http://blog.lolily.com/wordpress-plugin-mp-ukagaka.html
2.安装了“wordpress连接微博”插件。详见这里http://www.smyx.net/

准备新开一个栏目,外文翻译栏目,用来提高一下自己的英语水平。也为了更好的了解最新的动态,毕竟最新的东西都在国外。

0%