今天遇到?jin)需要在 javascript 中(h)承的问题Q?/span>
查了(jin)一些帖子,自己又写?jin)几个例子测试?jin)一下,ȝ如下Q?/span>
js 中实现(h)承有三种Ҏ(gu)Q?/span>
假设父类?/span> Parent, 子类?/span> Child,
W一U,子类强制调用父类构?/span>
function Child(){
(tng) (tng) (tng) (tng) (tng) (tng) Parent.call(this);
}
W二U,子类间接调用父类构?/span>
function Child(){
(tng) (tng) (tng) (tng) (tng) (tng) this.base = Parent;
(tng) (tng) (tng) (tng) (tng) (tng) this.base();
}
W三U:(x)讄原型
function Child(){}
Child.prototype = new Parent();
q种方式虽然不够直观Q却应该是最有效率的方式?/span>
其实 js 本n是没有什么(h)承之cȝ概念的,只是Z(jin)使用利用 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的根据,当然也是可以试的)(j)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 对象有|(j)Q?/span> msdn 中有描述Q?/span>
然后执行 Parent(); q个时?/span> parent 的构造函数执行以下几步:(x)
1 、将 parent ?/span> prototype 拯?/span> object 区域Q这时覆盖了(jin)前面的区?/span> ( 好像试证明 parent 的原型ƈ不会(x)被拷贝,此步不会(x)被执?/span> )
2 、对q个区域执行初始化,也就是正常的 function 调用的过E。(相当?/span> Parent(),this 变量有|(j)
而普通的 function 调用应该是这个样子:(x)׃没有 new 操作W,所以没有ؓ(f)其分配当前的 this( 也没有空?/span> ),
this 被放C(jin) 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 中静(rn)态方法和cd例方法调用的区别的原理一栗?/span>
在实C(jin)对象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(){....} 可以了(jin)?/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(){
(tng) (tng) (tng) (tng) (tng) (tng) ..............
(tng) (tng) (tng) (tng) (tng) (tng) this.super_toString();
(tng) (tng) (tng) (tng) (tng) (tng) ..............
}
基本的方法,|上到处都是Q在 java 中就是在 web.xml 注册一?/span> Listener Q如下:(x)
<listener>
(tng) (tng) (tng) <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的和搜烦(ch)引擎?/span> spider 无法区分?/span>
2 、当 Tomcat 重启Ӟ加蝲?jin)上ơ持久化?/span> session Ӟ无法准确计算在线数?/span>
W二个问题我们可以不予考虑Q这?/span> tomcat 容器实现不标准的问题Q我们要解决的是的第一个问题,如何知道你的讉K的是真实的?/span>
?/span> js l过搜烦(ch)引擎 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 {
(tng) (tng) (tng) public SessionCounterServlet() {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) super();
(tng) (tng) (tng) }
(tng) (tng) (tng) public void doGet(HttpServletRequest request,
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) HttpServletResponse response) throws IOException,
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ServletException {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) process(request, response);
(tng) (tng) (tng) }
(tng) (tng) (tng) public void doPost(HttpServletRequest request,
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) HttpServletResponse response) throws IOException,
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ServletException {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) process(request, response);
(tng) (tng) (tng) }
(tng) (tng) (tng) public void process(HttpServletRequest request,
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) HttpServletResponse response) throws IOException,
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) ServletException {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) SessionCounter.put(request.getSession().getId());
}
}
我们可以看到q个 servlet 只是做了(jin)一件事情,?/span> process 里面做了(jin) SessionCounter.put(request.getSession().getId()); q个动作?/span>
我们来看看我们的 SessionCounter 做了(jin)些什么:(x)
import javax.servlet.http.*;
import java.util.Hashtable;
public class SessionCounter implements HttpSessionListener {
(tng) (tng) (tng) public SessionCounter() {
(tng) (tng) (tng) }
(tng) (tng) (tng) public static Hashtable m_real = new Hashtable();
(tng) (tng) (tng) private static long count = 0;
(tng) (tng) (tng) public void sessionCreated(HttpSessionEvent e) {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) count++;
(tng) (tng) (tng) }
(tng) (tng) (tng) public void sessionDestroyed(HttpSessionEvent e) {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) if (count > 0) {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) count--;
(tng) (tng) (tng) (tng) (tng) (tng) (tng) }
(tng) (tng) (tng) (tng) (tng) (tng) (tng) m_real.remove(e.getSession().getId());
(tng) (tng) (tng) }
(tng) (tng) (tng) public static long getSessionCount() {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) return count;
(tng) (tng) (tng) }
(tng) (tng) (tng) public static void put(String sessionId){
(tng) (tng) (tng) (tng) (tng) (tng) (tng) m_real.put(sessionId,"1");
(tng) (tng) (tng) }
(tng) (tng) (tng) public static int getRealCount(){
(tng) (tng) (tng) (tng) (tng) (tng) (tng) return m_real.size();
(tng) (tng) (tng) }
}
我们记录?jin)一个静(rn)态的 hash 表来记录Ȁzȝ态的 sessionid Qƈ?/span> session 销毁的时候将q个 sessionid |ؓ(f)I?/span>
怎么?/span> servlet 配置?/span> web 应用中我׃|唆?jin)?/span>