谁动了我的代码

抽象即是空,空即是抽象。
posts(43) comments(24) trackbacks(0)
  • BlogJava
  • 联系
  • RSS 2.0 Feed 聚合
  • 管理

News

所有文章版权归我所有,转载请注明出处,谢谢!

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论

留言簿

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔分类

  • Android开发(5)
  • C/C++(1)
  • DataBase(3)
  • Java(16)
  • JavaScript(14)
  • WEB前端(1)
  • 编程杂项(2)
  • 网络(1)

随笔档案

  • 2016年5月 (1)
  • 2011年2月 (1)
  • 2010年6月 (3)
  • 2010年5月 (1)
  • 2009年12月 (2)
  • 2009年11月 (1)
  • 2009年10月 (2)
  • 2009年6月 (2)
  • 2009年5月 (1)
  • 2009年4月 (2)
  • 2009年3月 (4)
  • 2009年2月 (1)
  • 2009年1月 (1)
  • 2008年12月 (1)
  • 2008年11月 (1)
  • 2008年10月 (4)
  • 2008年9月 (2)
  • 2008年5月 (5)
  • 2008年3月 (3)
  • 2007年12月 (2)
  • 2007年10月 (1)
  • 2007年9月 (2)
  • 2007年5月 (1)

搜索

  •  

最新评论

  • 1. re: Android之ImageView载入网络上的图片
  • 222222222222222222222
  • --2222222222222222222222222222
  • 2. re: Log4j自带Log Viewer的用法
  • 执行你的根本不行,乱错帖子就在这乱贴,tmd
  • --asdf
  • 3. re: Android之使用私有存储
  • getDir方法创建的文件,会有个app_前缀,请问这怎么去掉呢?
  • --就是宝宝
  • 4. re: Android通用事件造成的生命周期变化情况
  • 我相信以后Android将成为越来越多设备的OS,不光是手持上网设置,冰箱、洗衣机都有可能采用Android。
  • --淘宝网女装春装新款
  • 5. re: Android通用事件造成的生命周期变化情况
  • 不错
  • --歌瑞尔内衣

阅读排行榜

评论排行榜

关于JavaScript的cloneNode方法对于节点上的事件clone问题的研究。

我的测试环境是IE8,对于事件clone要注意一下3点:
1.运行时添加的事件不会被克隆,如下例:

1a = document.getElementById('a'); //假设a是一个div
2   a.onclick = function () { alert(this.innerHTML); }
3b = a.cloneNode();

2.解析HTML时原来带的事件会被克隆,如下例:
1<div id='a' onclick='alert(this.innerHTML)'>aaaa</div>

3.通过attachEvent添加的事件会被克隆,如下例:
1a = document.getElementById('a');
2    a.attachEvent('onclick', function () {
3          alert(this.innerHTML);
4    }
);
5b = a.cloneNode();

最后如果想在clone时将节点其中的子节点一同clone的话,请使用cloneNode(true)。

posted @ 2009-10-18 13:28 Eric Song 阅读(1043) | 评论 (0) | 编辑 收藏

参考Prototype的Class.create写了一个类似的实现,但是不是Ruby like OOP,使用上更像Java。

实现代码:
 1 function $A (Arguments) {
 2     var result = [];
 3     for (var i = 0; i < Arguments.length; i++)
 4         result.push(Arguments[i]);
 5     return result;
 6 }
 7 
 8 Class = {
 9     create : function () {
10         var args = $A(arguments);
11         var parentClass = args.shift();
12         var properties;
13         if (parentClass instanceof Function)
14             properties = args.shift();
15         else if (parentClass instanceof Object) {
16             properties = parentClass;
17             parentClass = void 0;
18         }
19         
20         var klazz = function () {
21             if (this.initialize) this.initialize.apply(this, arguments);
22         };
23         
24         if (parentClass) {
25             var tmpClass = new Function;
26             tmpClass.prototype = parentClass.prototype;
27             klazz.prototype = new tmpClass();
28             klazz.prototype.constructor = klazz;
29         }
30         
31         for (var key in properties) {
32             if (properties[key] instanceof Function && klazz.prototype[key] instanceof Function) {
33                 klazz.prototype[key] = (function () {
34                     var _parent = klazz.prototype[key];
35                     var _method = properties[key];
36                     return function() {
37                         var _this = this;
38                         $super = function(){
39                             _parent.apply(_this, arguments);
40                         }
41                         _method.apply(this, arguments);
42                     }
43 
                })();
44             }
45             else 
46                 klazz.prototype[key] = properties[key];
47         }
48         
49         return klazz;
50     }
51 }

测试代码:
 1
 2             T = Class.create({
 3                 initialize : function (tt,mm) {
 4                     alert("initialize T");
 5                     this.tt = tt;
 6                     this.mm = mm;
 7                 },
 8                 l : function () {
 9                     alert("f");
10                 },
11                 f : function () {
12                     alert(123);
13                 }
14             });
15             
16             M = Class.create(T, {
17                 initialize : function (tt,mm,nn) {
18                     $super(tt,mm);
19                     alert("initialize M");
20                     this.nn = nn;
21                 },
22                 f : function () {
23                     //$super();  这里也可以不调用父类的f方法
24                     alert(456);
25                 },
26                 s : function () {
27                     alert("sssss");
28                 }
29             });
30             
31             N = Class.create(M);
32             
33             m = new N(1,2,3);
34             m.f();
35             m.l();
36             m.s();
37             alert(m.tt);
38             alert(m.mm);
39             alert(m.nn);
40             alert(m instanceof N);
41             alert(m instanceof M);
42             alert(m instanceof T);

在做的过程中,上面粗体部分不是像现在这样实现的,遇到了一个怪异的问题,下面给出原来的实现:
1 var _parent = klazz.prototype[key];
2 var _method = properties[key];
3 klazz.prototype[key] = function() {
4     var _this = this;
5     $super = function(){
6          _parent.apply(_this, arguments);
7     }
8     _method.apply(this, arguments);
9 }
这种实现造成了klazz的prototype中的每个方法执行总是返回相同结果,原因是_parent和_method在create一个Class的 时候已经被固定到properties的最后一个key上,所以在运行的时候会返回相同的结果,解决方法如同上面粗体部分,必须用一个函数封装并立即执行 返回内部函数,这是闭包的一种使用方式,这种做法类似把函数内的内容做一个快照,返回的内部函数存取变量的时候其实是从快照中取得,而不是从 properties中取得。

这个版本并不能用在生产环境中,由于时间仓促,肯定会有BUG或不完善的地方。所以建议大家还是使用Prototype的实现,我这个实现只是用来更加深刻的理解一些概念,比如变量作用域链、闭包等等的使用。

posted @ 2009-06-09 00:04 Eric Song 阅读(616) | 评论 (0) | 编辑 收藏

Tomcat乱码问题研究,附带AJAX乱码问题研究。

很奇怪测试了多个应用服务器,只有Tomcat出现了乱码问题。让我们来分析一下原因,测试环境是Tomcat5.5.27,字符集编码统一为UTF-8。

1.页面静态内容乱码(非动态生成内容乱码)
这一般是<%@ page pageEncoding="UTF-8" %>设置的问题,建议在每个页面上都加上pageEncoding设定,让应用服务器能正确把JSP文件按照设定的编码转换为Java文件,只要这个pageEncoding设置正确就可以避免静态内容的乱码。有人可能会说我没有设置也没有乱码,那是因为应用服务器还可以读取<%@ page contentType="text/html; charset=UTF-8" %>中的charset作为备选方案,虽然这是JSP规范中要求的,但是难保有的容器没有实现或实现有BUG,所以有时候在某个应用服务器下(如Tomcat)不设置pageEncoding也可以,但是同样的页面拿到别的应用服务器下就不能保证不出现乱码。

2.动态生成内容乱码
新下载的Tomcat没有经过任何特殊的设置,无论是GET和POST都出现乱码。首先设置HTTP Connector(server.xml中监听8080端口的那个Connector),加上URIEncoding="UTF-8",消除了GET乱码,再在JSP页面中第一句加入<% request.setCharacterEncoding("UTF-8"); %>,消除了POST乱码。
通过上面两个设置我们发现,URIEncoding控制的是GET字符集编码,Request的CharacterEncoding控制的是POST字符集编码。
如果没有上面那句
<% request.setCharacterEncoding("UTF-8"); %>,在页面起始加入<%= request.getCharacterEncoding() %>,在Tomcat下我们发现输出null,在其他服务器下却输出UTF-8。这就是为什么在Tomcat下应该正确设置Request的CharacterEncoding的原因。
上面提到的<%@ page contentType="text/html; charset=UTF-8" %>,除了声明返回给客户端的流是text/html外,同时设置了Response的CharacterEncoding,即相当于执行了Response.setCharacterEncoding("UTF-8")这段代码。它保证了服务器端生成的动态内容到达客户端也不会乱码。
但有一种情况下也不会出现乱码,就是如下例这种情况,前提是没有设置
Request的CharacterEncoding:
1 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2     response.getWriter().write(request.getParameter("xxxxx"));
3 }
这种情况下提交过来的表单数据其实是ISO-8859-1的编码,而返回给客户端又没有<%@ page contentType="text/html; charset=UTF-8" %>的设置,所以还是ISO-8859-1的编码,但是为什么没有乱码呢?其实已经乱码了,如果在第2行下断点的话,会发现request.getParameter("xxxxx")的返回值就是乱码。可以用一句Java代码来解释为什么客户端显示结果没有乱码,如下:
1 System.out.println(new String("你好,世界".getBytes("ISO-8859-1"), "ISO-8859-1");
很奇怪这句代码,明明是中文,应该用GB2312或GBK之类的字符集编码来getBytes,却用了ISO-8859-1,事实证明,这种互逆操作对字符串本身没有任何影响,只要getBytes和new String的时候字符集编码是一致的就不会引起乱码。
上面这句代码正好说明了数据从客户端POST到服务器端时是ISO-8859-1编码,然后从服务器端写回到客户端还是ISO-8859-1编码,所以就没有造成乱码,如果这里不是直接写回到客户端,而是forward到另一个JSP页面,而这个页面恰好使用了
<%@ page contentType="text/html; charset=UTF-8" %>来设置Response的CharacterEncoding,那么在页面中输出xxxxx还会产生乱码,同样用一句Java代码来解释,如下:
1 System.out.println(new String("你好,世界".getBytes("ISO-8859-1"), "UTF-8"));
所以,最后结论是如果想POST到服务器端不乱码就要设置Request的CharacterEncoding,写回到客户端不乱码就要设置Response的CharacterEncoding,若是JSP页面要设置<%@ page contentType="text/html; charset=UTF-8" %>。

3.AJAX乱码问题(不借助任何JS框架,像Prototype之类的框架会对GET请求的queryString自动应用encodeURIComponent()编码)
GET请求时,需要对queryString使用encodeURIComponent()编码之后再提交到服务器。这是XMLHttpRequest规范所要求的。
POST请求时,不需要使用encodeURIComponent()。
通过对应用程序下断点发现,GET请求和POST请求的数据发送到服务器端都是正常的没有乱码,但是服务器端生成的动态内容写回客户端却是乱码,说明Response的CharacterEncoding设置错误,反过来我们再想一下,我们根本就没有设置过Response的CharacterEncoding,为什么呢?因为我们是以AJAX的方式提交表单,返回后不像JSP页面那样有<%@ page contentType="text/html; charset=UTF-8" %>来设置Response的CharacterEncoding,所以就会出错。

综合上述,解决的办法就是各大网站提出的通用解决方案Filter,如果你的应用没有用到AJAX,只设置Request的CharacterEncoding即可,否则Response的CharacterEncoding也要设置。下面是一个Filter的示例,只引用doFilter方法来说明问题:


1 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
2     request.setCharacterEncoding("UTF-8");
3     response.setCharacterEncoding("UTF-8");
4     chain.doFilter(request, response);
5 }


posted @ 2009-06-07 23:47 Eric Song 阅读(1007) | 评论 (0) | 编辑 收藏

对JavaScript的变量作用域的理解

作用域是一个抽象概念,在浏览器的JavaScript实现中会有这个概念,但是不同浏览器实现可能不同。

一、作用域的种类(自己感悟)
1.对象作用域,window及标签元素都属于对象作用域。
2.函数作用域,函数自身形成的作用域。
可以把作用域看作是上下文(context)之类的对象。

看下面的代码
例0

 1breakE = 0;
 2var state = 1;                //1
 3Person = function(name) {     //2
 4    var age = 20;
 5    this.name = name;
 6    this.show = function () {     //3
 7        alert(age);
 8        alert(state);
 9        alert(name);
               alert(
this.name);
10    }

11    alert(m);
12}

13    Person.prototype.check = function () {};
14m = new Person('mike');       //4
15var j = new Person('Jerry');      //5
16
17m.show();                     //6
通过看上面这段代码我们发现有时候定义变量时用var,有时候却不用,这里有什么区别吗?在此之前我们先定下规矩,那就是必须有一个全局作用域,就像是window对象的存在一样,是作用域的最顶层。那么哪些变量被定义到作用域的最顶层呢?那就是state,对于不在任何函数或类中用var定义的变量存在于全局作用域中。那么全局作用域属于作用域的哪种类型呢?那就是对象作用域。具体是哪个对象的作用域呢?非window对象莫属。

我们可以把对象作用域想像成两部分,左面部分是对象级别的,保存的是和对象绑定的成员属性(无论是变量还是函数),通过this来访问的。右面的部分是作用域级别的,保存的是var定义的属性(无论是变量还是函数),可以直接通过变量名称访问。对于window来说它是个特殊体,从用var定义的变量可以用this来访问就能看出问题,我个人猜测window对象既是JavaScript的顶层对象又是顶层作用域,所以才会有这种效果。
另一种情况就是标签元素的对象作用域和全局作用域非常的像,如下例:
 1//例1
 2<input type='button' value='click me' onclick='alert(value)'/>
 3//例2
 4<input type='button' value='click me' onclick='alert(this.value)'/>
 5//例3
 6function test() {
 7    alert(value);
 8    alert(this.value);
 9}

10<input type='button' value='click me' onclick='test()'/>
很奇怪为什么例1和例2访问value和全局作用域里的var定义的变量的行为是一致的,按理说value应该属于input标签元素对象的成员属性,访问对象的成员属性应该用this来访问,我们自定义的类,如果成员方法想访问成员变量都需要加this的,就像最上面的例子里的this.show方法访问this.name成员变量一样。而对于例3,勤快的读者如果运行一下便知一定会出错的,第一句系统会报value未定义(除非你在全局作用域定义过value变量),第二句会打印出undefined。为什么会这样呢?这就要引出作用域链这个概念了,后面会解释这个概念的。

反观函数作用域,由于函数中用var定义的变量不能用this来访问,所以在函数作用域中不再像对象作用域那样分两部分,而this实际保存的是与该函数绑定的对象的引用,也就是说this在函数中有特殊的含义,是不能挪作它用的。

二、作用域链
作用域是可以嵌套的,而嵌套的结果就形成了作用域链,如例0所示,我们来描述一下作用域链:
全局作用域<----Person函数作用域<-----show函数作用域
在全局作用域中可以访问哪些变量呢(注意我现在指的只是作用域中的变量)?
1.state
2.j
在Person函数作用域中可以访问哪些变量呢?
1.全局作用域中的所有可访问的变量
2.name(参数)
3.age
在show函数中又有哪些变量可以被访问呢?
1.全局作用域中的所有可访问变量
2.Person函数作用域中所有可访问变量
3.如若show函数中还定义了var变量也要加入show函数作用域

如果在show中访问一个x变量,首先从show函数作用域里查是否有x这个变量,如果没有再查Person作用域,如果还没有的话再查全局作用域,找到就返回该变量。
讲解到这里我们发现一个问题,似乎作用域是定义时生成块级作用域(即单独的对象作用域和函数作用域)而运行时生成作用域链,这就是词法作用域的由来。有了这种作用域就构成了闭包的基础。
下面是一个稍微特殊的例子:
 1 function test() {
 2     test2();
 3 }
 4 
 5 function test3() {
 6     test2 = function() {
 7         alert("test2");
 8     }
 9     test();
10 }
定义test的时候test2还不存在,但是调用test的时候,test2就存在了,这说明了作用域链确实是运行时生成的。

通过作用域链如何解释例1、2、3呢?
我的分析是对于HTML元素来说当页面解析的时候,元素被解析成DOM树,HTML元素里的标准属性作为该元素对象作用域的变量(类似var定义的那种),而非该元素DOM对象的成员属性(类似this定义的那种),这样就解释了两个问题:
1.在页面上预定义的HTML元素标准属性是不能用delete和removeAttribute删除的。
2.onclick属于input元素的一个方法,那么这个作用域链应该像下面这样:
   全局作用域<-----HTML元素作用域<-------onclick函数作用域
   value变量在哪个作用域里呢?答案是HTML元素作用域中。所以onclick不但可以访问而且加不加this都可以。
那么例3的作用域链是什么样的呢?如下:
    全局作用域<-----test函数作用域
    全局作用域<-----HTML元素作用域<-------onclick函数作用域
没错是两条,因为当单击按钮后执行到onclick函数中时走的是第二条链,而在onclick中调用了test函数时,走的是第一条链。
显然value还是定义在HTML元素作用域中,而test想访问value值一定是访问不到的。

对于这个问题我还测试了一下非标准属性,如下例:
1<input type="button" value="click me" bb="123" onclick="delete this.bb; alert(bb)"/>
测试发现非标准的HTML元素属性可以被删除,但是delete语句执行时必须用this来引用(IE中测试),直接访问如alert到没有这个限制。
说明bb是input对象属性是没错的,因为它可以被删除,但是如果它没有被删除的话alert(bb)还是能显示出来的,说明这类属性很特殊,具体怎么解释我还没有想好,如果有朋友能解释的通,请告知我。

三、什么是闭包
show函数显然是一个闭包,但是它是由类的构造函数生成的,和另一种形式其实是一样的,代码如下:
 1function getFunc (a, b) {
 2    return function () {
 3         alert(a - b);
 4    }

 5}
 
 6
 7var func1 = getFunc(10,5);
 8func1();
 9
10var func2 = getFunc(20,30);
11func2();
上面的代码func1函数无论我执行多少次都显示5,func2函数无论我执行多少次都显示-10,这和例0是多么的像呀,例0中m.show()无论执行多少次都能显示'mike',j.show()无论执行多少次都能显示'Jerry'(行号9那行在起作用,先不考虑this.name那行)。这就是闭包,把作用域链中变化的变量给固定化,然后把作用域链和函数本身进行绑定,无论我在什么地方执行函数,函数的作用域链始终是它定义的时候那条。

四、关于对象成员的访问(即this能引用的那些属性),我只是在猜想,可能的作用域链应该如下:
    全局作用域<-------m对象作用域<-------m.test函数作用域
    m的对象成员(类中this定义的)保存在对象作用域的左半部,m的作用域变量(类中var定义的)保存在对象作用域的右半部。
    m.test函数要访问对象成员时从对象作用域的左半部检索,要访问作用域变量时从对象作用域的右半部检索。
    同时这个作用域链还解答了另一个问题,即原型方法(公共方法)为什么不能访问类中用var定义的变量。
    看例0即可知check和Person根本就不在同一个链上,又谈何能访问呢?

至此把JavaScript变量作用域讲解完毕,我觉得这个还是蛮重要的,如果一定要有个比较的话,应该和Java中的ClassLoader有同样的重要性吧。大家借鉴的同时请多给我指出错误,因为这其中有一些还是我的猜测。

posted @ 2009-05-19 02:06 Eric Song 阅读(512) | 评论 (0) | 编辑 收藏

关于CSS的Position的两篇好文章

区分CSS中position定位属性absolute与relative

CSS教程:CSS中的定位(position)

posted @ 2009-04-18 15:03 Eric Song 阅读(150) | 评论 (0) | 编辑 收藏

IE document compatMode

compatMode Property

Gets a value that indicates whether standards-compliant mode is switched on for the object.

Syntax

 [ sMode = ] object.compatMode

Possible Values

sMode String that receives one of the following values.
BackCompatStandards-compliant mode is not switched on.
CSS1CompatStandards-compliant mode is switched on.

The property is read-only. The property has no default value.

Remarks

With Microsoft Internet Explorer 6 and later, you switch on standards-compliant mode by including the !DOCTYPE declaration at the top of your document, specifying a valid Label in the declaration, and in some cases, specifying the Definition or URL. The Label element specifies the unique name of the Document Type Definition (DTD), and can be appended with the version number of the DTD. The Definition element specifies the definition of the DTD that is specified in the Label. The URL element specifies the location of the DTD.

When standards-compliant mode is switched on (also called "strict mode"), Windows Internet Explorer displays the document according to the World Wide Web Consortium (W3C) Cascading Style Sheets (CSS) World Wide Web link standard. When standards-compliant mode is not switched on (also called "quirks mode"), the document is displayed as it was displayed in previous versions of Internet Explorer.

 New for Internet Explorer 8 The compatMode property is deprecated in Internet Explorer 8 in favor of the documentMode property.




IE8 documentMode

Syntax

[ vMode = ] object.documentMode

Possible Values

vMode Floating-point that receives one of the following values.
5Microsoft Internet Explorer 5 mode (also known as "quirks mode").
7Internet Explorer 7 Standards mode.
8Internet Explorer 8 Standards mode.

The property is read-only. The property has no default value.

Remarks

This property is available in all compatibility modes.

The document compatibility mode of a Web page determines how Internet Explorer 8 interprets and renders the page. Page authors generally use meta elements to specify X-UA-Compatible HTTP-EQUIV headers that specify the document compatibility mode. For more information, see Defining Document Compatibility. In versions of Internet Explorer previous to Internet Explorer 8, compatMode was solely determined by DOCTYPE.

posted @ 2009-04-15 17:37 Eric Song 阅读(498) | 评论 (0) | 编辑 收藏

Oracle Distinct注意事项

在使用Distinct时,不能直接对count操作,需要通过子查询来实现,如下
select count(1) from (select distinct * from table_name)

posted @ 2009-03-19 20:49 Eric Song 阅读(791) | 评论 (0) | 编辑 收藏

Oracle数据库建立Synonym

通过dblink查询表  select * from schema_name.table_or_view_name@dblink
建立Synonym     create synonym synonym_name for schema_name.table_or_view_name@dblink

posted @ 2009-03-19 20:48 Eric Song 阅读(183) | 评论 (0) | 编辑 收藏

JavaScript对form及form中的引用。

通常我们对form的引用通过给form加上id来实现,其实我们可以使用name来实现。两者的不同是id需要用document.getElementById()来检索,name通过document.forms[form_name]来检索,在form中的表单元素都有name的时候可以通过document.forms[form_name][element_name]来检索到指定的表单元素。另一种方法可以通过document.forms[form_name].elements来获得表单元素的集合,但是其中不包括input type='image',所有这些方法在IE7、Opera、FF2、FF3、Chrome、Safari上测试通过。

posted @ 2009-03-19 20:44 Eric Song 阅读(263) | 评论 (1) | 编辑 收藏

jad和Java Decompiler的小小不同

今天用Java Decompiler反编译一个类发现其中字符串连加的代码反编译的结果和jad的不同。
源码一般somestr = "a" + "b" + "c" + "d" ....;

jad反编译过来会自动生成一个StringBuffer,然后把各个子串append到一起。如:
somestr = (new StringBuilder(String.valueOf("a"))).append("b").append("c").append("d")....).toString();

Java Decompiler反编译的代码基本上和原来一样,有字节码查看工具看出,编译器确实对字符串相加做了优化。请在eclipse使用byte outline插件查看。但是有一种情况是例外的,如:
somestr = "a" + "b";
somestr += "c" + "d";
编译器会为每一条语句建立一个StringBuilder,像上面的情况请把两句合并成一句。

posted @ 2009-03-10 11:25 Eric Song 阅读(1161) | 评论 (2) | 编辑 收藏

仅列出标题
共5页: 上一页 1 2 3 4 5 下一页 
 
Powered by:
BlogJava
Copyright © Eric Song