今天遇到了需要在 javascript 中承的问题Q?/span>
查了一些帖子,自己又写了几个例子测试了一下,ȝ如下Q?/span>
js 中实现承有三种Ҏ(gu)Q?/span>
假设父类?/span> Parent, 子类?/span> Child,
W一U,子类强制调用父类构?/span>
function Child(){
Parent.call(this);
}
W二U,子类间接调用父类构?/span>
function Child(){
this.base = Parent;
this.base();
}
W三U:(x)讄原型
function Child(){}
Child.prototype = new Parent();
q种方式虽然不够直观Q却应该是最有效率的方式?/span>
其实 js 本n是没有什么承之cȝ概念的,只是Z使用利用 js 的一些特性而加的?/span>
js 的原型方?/span> prototype, 使得许多的工作变得容易?/span>
一?/span> function 对象和根?/span> function 构造出来的对象是不同的?/span>
一?/span> function 对象的原型其实就是一个根?/span> function 对象构徏出来的对象?/span>
CQ这个对象可?/span> new 出来的对象不一栗在 function 内部的代码ƈ不会(x)被执行,如:(x)
this.funcName = function() q样的代码。?/span> new 出来的对象则不然Q他h执行后的对象Ҏ(gu)?/span>
function 的局部变量相当于 class 里的U有变量Q无法在子类中获取和操作。但 this. 的部分是可以的?/span>
Q这是我推断的,没有M的根据,当然也是可以试的)Q?/span>
当一?/span> Child ?/span> new ӞW一二种Ҏ(gu)中, js 执行?/span>
1 、先分配一个空_(d)Q相当于 this = new Object() Q?/span> (msdn 中有具体的描q?/span> )
2 、拷贝原型:(x)
3 、执行构造:(x)也就?/span> Child.call(this) Q相当于 child(), 此时 this 对象有|Q?/span> msdn 中有描述Q?/span>
然后执行 Parent(); q个时?/span> parent 的构造函数执行以下几步:(x)
1 、将 parent ?/span> prototype 拯?/span> object 区域Q这时覆盖了前面的区?/span> ( 好像试证明 parent 的原型ƈ不会(x)被拷贝,此步不会(x)被执?/span> )
2 、对q个区域执行初始化,也就是正常的 function 调用的过E。(相当?/span> Parent(),this 变量有|
而普通的 function 调用应该是这个样子:(x)׃没有 new 操作W,所以没有ؓ(f)其分配当前的 this( 也没有空?/span> ),
this 被放C window 对象上。但?/span> new 的时候显然不是这栗?/span>
obj.func() 的调用和 func() 调用是完全不一L(fng)Q?/span> obj.func ?/span> this 对象?/span> obj 对象Q?/span> func() 调用 this 对象?/span> window 对象Q这个应该和 jvm 中静态方法和cd例方法调用的区别的原理一栗?/span>
在实C对象l承之后Q我开始面临到W二个问题,重蝲?/span>
js 怎样实现重蝲?/span>
1 、简单的重蝲Q?/span>
在这U重载中Q子cȝҎ(gu)无需调用父类的方法,直接在执行父cL造之后,再执行子cȝ重蝲Ҏ(gu)Q如 Parent ?/span> toString() Ҏ(gu)Q这时只需执行 this.toString = function(){....} 可以了?/span>
2 、调用父cL法的重蝲Q?/span>
׃ js 实际q行时ƈ没有父类、子cM个实例空_(d)所?/span> super.toString() 肯定是不行的Q而在子类?/span> toString Ҏ(gu)中进?/span> this.toString() 调用只能引v内存溢出Q其实这U也可以惛_法做到?/span>
this.super_toString = this.toString();
this.toString=function(){
..............
this.super_toString();
..............
}
基本的方法,|上到处都是Q在 java 中就是在 web.xml 注册一?/span> Listener Q如下:(x)
<listener>
<listener-class>xp.web.SessionCounter</listener-class>
</listener>
SessionCounter.java 实现 javax.servlet.http.HttpSessionListener 接口Q分别在 sessionCreated Ҏ(gu)?/span> sessionDestroyed Ҏ(gu)中处?/span> session 数目?/span>
q样的方法有一定的问题Q?/span>
1 、对于真正从|页讉K的和搜烦引擎?/span> spider 无法区分?/span>
2 、当 Tomcat 重启Ӟ加蝲了上ơ持久化?/span> session Ӟ无法准确计算在线数?/span>
W二个问题我们可以不予考虑Q这?/span> tomcat 容器实现不标准的问题Q我们要解决的是的第一个问题,如何知道你的讉K的是真实的?/span>
?/span> js l过搜烦引擎 Q?/span>
做过 pv l计的都知道Q可以用 script 的方式得C真实?/span> pageView 数目Q我们现在要做的是q样的一件事情,我们在所有的面都加入一D话Q?/span>
<script type="text/javascript">
document.write ("<iframe src='/sessionCountServlet' width=0 height=0 frameborder=no border=0 MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=no></iframe>");
</script>
然后我们写上一?/span> servlet 来记录这些真正的讉K者?/span>
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionCounterServlet extends HttpServlet {
public SessionCounterServlet() {
super();
}
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
process(request, response);
}
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
process(request, response);
}
public void process(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
SessionCounter.put(request.getSession().getId());
}
}
我们可以看到q个 servlet 只是做了一件事情,?/span> process 里面做了 SessionCounter.put(request.getSession().getId()); q个动作?/span>
我们来看看我们的 SessionCounter 做了些什么:(x)
import javax.servlet.http.*;
import java.util.Hashtable;
public class SessionCounter implements HttpSessionListener {
public SessionCounter() {
}
public static Hashtable m_real = new Hashtable();
private static long count = 0;
public void sessionCreated(HttpSessionEvent e) {
count++;
}
public void sessionDestroyed(HttpSessionEvent e) {
if (count > 0) {
count--;
}
m_real.remove(e.getSession().getId());
}
public static long getSessionCount() {
return count;
}
public static void put(String sessionId){
m_real.put(sessionId,"1");
}
public static int getRealCount(){
return m_real.size();
}
}
我们记录了一个静态的 hash 表来记录Ȁzȝ态的 sessionid Qƈ?/span> session 销毁的时候将q个 sessionid |ؓ(f)I?/span>
怎么?/span> servlet 配置?/span> web 应用中我׃|唆了?/span>