`
jianguang_qq
  • 浏览: 91803 次
  • 性别: Icon_minigender_1
  • 来自: 深圳南山
社区版块
存档分类
最新评论

【JS优化系列】从一个计时器的写法探讨js多种实现方式的优劣

阅读更多

      前几天帮erricwang写一个js计时器,发现可以用有很多种方式实现相同的功能。现将它写下来,和大家一起探讨分析比较。

 

实现一:

<body>
<div id="time1">time1</div>
<div id="time2">time2</div>
</body>
<script>
function Timer(id){
	this.id = id;
	this.begin = function(count){
		this.show(this.id, count)();
		setInterval(this.show(this.id, count-1),1000);
	}
	this.show = function(id, count){
		return function(){
			document.getElementById(id).innerHTML = count<0 ? "over" :count;
			count--;
		}
	}
} 

t1 = new Timer("time1");
t1.begin(50);

t2 = new Timer("time2");
t2.begin(10);
</script>

 

   且看第一种实现,显然这里有一个很不好的地方,计时完成之后,setInterval没有被clear,严重影响了性能。

 

实现二:

function Timer(id){
	this.id = id;
	this.timer = null;
	this.count = 0;
	this.begin = function(count){
		this.count = count;
		this.show(this)();
		this.timer = setInterval(this.show(this),1000);
	}
	this.show = function(obj){	
		return function(){
			if(obj.count < 0){
				document.getElementById(obj.id).innerHTML = "over";
				clearInterval(obj.timer);
				return ;
			}
			document.getElementById(obj.id).innerHTML = obj.count;
			obj.count--;
		}
	}
} 

       实现二解决了实现一的setInterval未被clear的问题,看上去也很“完美”,且看下面:

alert(t1.show == t2.show) //结果false
alert(t1.begin == t2.begin) //结果false

      很明显这里Timer每个实例都复制了一份show和begin,二不是共享同一份的,所以t1.showt和2.show所指向的并非同一份实现,这样对性能多少会有些影响。

 

实现三:

function Timer(id){
	this.id = id;
	this.timer = null;
	this.count = 0;
	this.begin = function(count){
		this.count = count;
		Timer.show(this)();
		this.timer = setInterval(Timer.show(this),1000);
	}
	Timer.show = function(obj){	
		return function(){
			if(obj.count < 0){
				document.getElementById(obj.id).innerHTML = "over";
				clearInterval(obj.timer);
				return ;
			}
			document.getElementById(obj.id).innerHTML = obj.count;
			obj.count--;
		}
	}
} 

      这里实现了让所有实例共享一份show函数:

alert(t1.begin == t2.begin) //结果true 

 

实现四:

 

function Timer(id){
	this.id = id;
	this.timer = null;
	this.count = 0;
	this.begin = function(count){
		this.count = count;
		this.show(this)();//注意和实现三的区别:这里不是Timer.show(this)();
		this.timer = setInterval(this.show(this),1000);//注意和实现三的区别:这里不是Timer.show(this)();
	}
} 
Timer.prototype.show = function(obj){	
	return function(){
		if(obj.count < 0){
			document.getElementById(obj.id).innerHTML = "over";
			clearInterval(obj.timer);
			return ;
		}
		document.getElementById(obj.id).innerHTML = obj.count;
		obj.count--;
	}
}

      实现三和实现四很有意思:二者都实现了让所有实例共享一份show方法。

      区别是:实现三show作为Timer对象的一个属性,这里有点类似与java的静态方法,show方法是属于Timer对象本身的,而不是其实例(t1、t2...)的,所以需要用Timer.show(..)来调用;而实现四采用了“原型”prototype方式来实现,这里show方法不是Timer对象本身,而是其实例(t1、t2...)的,所以使用this.show(..)或者t1.show(...)来调用,这里很有意思“原型”创建的属性是属于其实例的,而且所有实例共享同一份实现(不知道我这里的理解是否正确,欢迎大家拍砖)。这多少有些让学java等面向对象语言的人难以理解,而这也正式js有意思的地方。

      那么这两种实现方式那种更优呢?欢迎各位讨论。

 

实现五:

 

function Timer(id){
	this.id = id;
	this.timer = null;
	this.count = 0;

}
Timer.prototype.begin = function(count){
	this.count = count;
	this.show(this)();//注意这里不是Timer.show(this)();
	this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();
}
Timer.prototype.show = function(obj){	
	return function(){
		if(obj.count < 0){
			document.getElementById(obj.id).innerHTML = "over";
			clearInterval(obj.timer);
			return ;
		}
		document.getElementById(obj.id).innerHTML = obj.count;
		obj.count--;
	}
} 

      这里将begin也使用原型实现,可能这种写法让你看起来不太舒服,那我们换一种。

 

实现六:

 

function Timer(id){
	this.id = id;
	this.timer = null;
	this.count = 0;
}
Timer.prototype = {
	begin : function(count){
		this.count = count;
		this.show(this)();//注意这里不是Timer.show(this)();
		this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();
	},
	show : function(obj){	
		return function(){
			if(obj.count < 0){
				document.getElementById(obj.id).innerHTML = "over";
				clearInterval(obj.timer);
				return ;
			}
			document.getElementById(obj.id).innerHTML = obj.count;
			obj.count--;
		}
	} 
}

      或者,再换一种。

 

实现七:

 

function Timer(id){
	this.id = id;
	this.timer = null;
	this.count = 0;
	Timer.prototype.begin = function(count){
		this.count = count;
		this.show(this)();//主要这里不是Timer.show(this)();
		this.timer = setInterval(this.show(this),1000);//主要这里不是Timer.show(this)();
	}
	Timer.prototype.show = function(obj){	
		return function(){
			if(obj.count < 0){
				document.getElementById(obj.id).innerHTML = "over";
				clearInterval(obj.timer);
				return ;
			}
			document.getElementById(obj.id).innerHTML = obj.count;
			obj.count--;
		}
	} 
}

       这方式,看起来是不是更优雅一些呢。以上都采用面向对象的方式来实现的。那我们是否还可以采用其他方式实现呢? 

 

实现八:

var Timer = {
	begin : function(id,count){
		var obj = {};
		obj["id"] = id;
		obj["count"] = count;
		Timer.show(obj)();
		obj["timer"] = setInterval(Timer.show(obj),1000);//注意这里不是Timer.show(this)();
	},
	show : function(obj){	
		return function(){
			if(obj["count"] < 0){
				document.getElementById(obj["id"]).innerHTML = "over";
				clearInterval(obj["timer"]);
				return ;
			}
			document.getElementById(obj["id"]).innerHTML = obj["count"] ;
			obj["count"]--;
		}
	}
}

Timer.begin("time1", 30);
Timer.begin("time2", 60);

       这里采用了对象字面量的方式来实现的。对象字面量其实是一种单例模式,用在这里其实很变扭,本文这里引入只是引入一种js实现方式而已,仅供大家探讨。下一例也一样。

 

实现九:

 

var Timer = (function(){
	var items = {};
	function begin(id,count){
		var obj = {};
		obj["id"] = id;
		obj["count"] = count;
		Timer.show(obj)();
		obj["timer"] = setInterval(Timer.show(obj),1000);//注意这里不是Timer.show(this)();
		Timer.items[id] = obj;
	};
	function show(obj){	
		return function(){
			if(obj["count"] < 0){
				document.getElementById(obj["id"]).innerHTML = "over";
				clearInterval(obj["timer"]);
				return ;
			}
			document.getElementById(obj["id"]).innerHTML = obj["count"] ;
			obj["count"]--;
		}
	}
	return {
		items : items,
		begin : begin,
		show : show
	}
})()

Timer.begin("time1", 30);
Timer.items["time1"]["count"] = 80;//重新从80开始计时
Timer.begin("time2", 60);

       这里其实也是采用的对象字面量的方式来实现的,只是采用了闭包而已,应用闭包可以真正的实现属性私有化(不过这里没有体现出来)。这里还加了items属性,让其所有实例保存起来,以便后面还可以调用。

 

      平常用的比较多的还有最后一种闭包结合对象字面量的方式(不过在这个场景个人觉得用面向对象方式来实现更好一些)。对象字面量的方式其实也是js的单例模式,在js里应用很广泛,不过在这里应用好像不太合适,看这里的最后两个实现都觉得很牵强。

      从一个小小的计时器,可以衍生出如此多的方式来实现,真让人惊叹于js表现形式之丰富。如此众多实现方式,都有其优点和缺点,在不同的场合也有不同的应用。这里只是表达了一下个人的理解和观点,欢迎大家一起讨论js各种实现方式的优缺点及其适用场合。也欢迎拍砖,或者提供更好的实现方法。

 

 

【本人发帖抛砖引玉,希望能够引出更多的“玉”来,希望所写的每一段代码都能够得到一种最“优雅”的实现方式。以后本人会抛出更多的“砖”,希望能引来更多的“玉”,以供大家一起学习进步】

 

-------------------------------------------------------2009.08.17------------------------------------------------------------

 

到目前为止,个人觉得3楼zbm2001 的实现最优,让我学到了不少,希望能有更多的牛人来提供更优的实现。

function Timer(id){
	this.element = document.getElementById(id);
	this.timer = null;
	this.count = 0;
}
Timer.prototype = {
	begin : function(count){
		this.count = count;
		this.show();
		var _this = this;
		this.timer = setInterval(function(){_this.show();}, 1000);
	}
	,
	show : function(){
		this.element.innerHTML = this.count < 0 ? clearInterval(this.timer) || "over" : this.count--;
	} 
}

 

 

-------------------------------------------------------2009.08.21------------------------------------------------------------

继续收集评论中的实现方式,优劣请读者自评

janpoem

var Timer = function(id) {
	
	var _step = 500, _count = 0, _ticktark = 0, _element = document.getElementById(id);
	
	function __clear() {
		if (_ticktark != null) clearInterval(_ticktark);
	}
	
	return {
		
		begin: function(count, step) {
			if (_element && count > 0) {
				// 看看起始值多少,主要看看有没有被污染
				console.log('on start:', 'count:', _count, 'step:', _step);
				__clear();
				_step = step;
				_count = count;
				// 再看看
				console.log('on set:', 'count:', _count, 'step:', _step);
				_ticktark = setInterval(this.show, _step)
			}
			return this;
		},
		
		show: function() {
			_element && (_element.innerHTML = _count > 0 ? _count-- : 'over');
			if (_count <= 0) {
				console.log(_count);
				__clear();
			}
			return this;
		}
	}
}	

Timer('time1').begin(20, 100);
Timer('time2').begin(30, 200);

 

lifesinger

function Timer(id) {
    this.container = document.getElementById(id);
}

Timer.prototype = {

    constructor: Timer,

    begin: function(count) {
        var container = this.container;
        setTimeout(function() {
            container.innerHTML = count > 0 ? count-- : "over";
            if(count + 1) {
                setTimeout(arguments.callee, 1000);
            }
        }, 1000);
    }
    
};

new Timer("time1").begin(10);
 

 

 

分享到:
评论
32 楼 szcjlssx 2009-10-05  
我也回个
function Timer(count,id) {  
    var start=count,obj=document.getElementById(id);  
    do {  
        (function (count) {  
            setTimeout(function () {  
                obj.innerHTML=count;  
            },(start-count)*1000);  
        })(count);  
    } while (count--);  
} 



一个函数,不做构造了,直接调用就执行
Js代码
Timer(10,"oDiv");
31 楼 szcjlssx 2009-10-03  
我也回个
function Timer(count,id) {
	var start=count,obj=document.getElementById(id);
	do {
		(function (count) {
			setTimeout(function () {
				obj.innerHTML=count;
			},(start-count)*1000);
		})(count);
	} while (count--);
}

一个函数,不做构造了,直接调用就执行
Timer(10,"oDiv");
30 楼 cjj 2009-09-23  
<div class="quote_title">clone168 写道</div>
<div class="quote_div">
<p>放在Timer构造函数内部的话:</p>
<p> </p>
<pre name="code" class="js">function Timer(id){   
    this.id = id;   
    this.timer = null;   
    this.count = 0;   
    Timer.prototype = { 
        begin : function(count){   
            //alert(this); 
            this.count = count;   
            this.show(this)();//注意这里不是Timer.show(this)();   
            this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();   
        },   
        show : function(obj){      
            return function(){   
                if(obj.count &lt; 0){   
                    document.getElementById(obj.id).innerHTML = "over";   
                    clearInterval(obj.timer);   
                    return ;   
                }   
                document.getElementById(obj.id).innerHTML = obj.count;   
                obj.count--;   
            }   
        }   
    }; 
}  </pre>
<p> </p>
 很奇怪,不知道什么原因
<p> </p>
</div>
<p>其实只要把例子构造得稍微复杂点的例子,就很容易理解这个问题了</p>
<p> </p>
<pre name="code" class="js">function Timer(id){   
    this.id = id;   
    this.timer = null;   
    this.count = 0;
this.begin=function(count){
alert('this:'+id); 
            this.count = count;   
            this.show(this)();//注意这里不是Timer.show(this)();   
            this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();   
}

    Timer.prototype = {
id:"abcd",
        begin : function(count){   
alert('prototype'); 
            this.count = count;   
            this.show(this)();//注意这里不是Timer.show(this)();   
            this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();   
        },   
        show : function(obj){      
            return function(){   
                if(obj.count &lt; 0){   
                    document.getElementById(obj.id).innerHTML = "over";   
                    clearInterval(obj.timer);   
                    return ;   
                }   
                document.getElementById(obj.id).innerHTML = obj.count;   
                obj.count--;   
            }   
        }   
    }; 
}

new Timer('aaa').begin(10);</pre>
29 楼 ferreousbox 2009-08-24  
其实是js类化的一个体现
// 声明一个类(其实也就是对象),其中initialize是构造方法
function MyObj(){this.initialize.apply(this, arguments);}

// 类的属性和方法声明
MyObj.prototype = {
    attr1 : null, // 属性,当然也可以在方法中直接this.attr1=来设置
   
    // 构造方法,可以直接new MyObje(args)
    initialize : function() {

    },

    // 一般方法
    func1 : function() {
   
    }
}

// 类的静态方法
MyObj.func2 = function() {

};
28 楼 clone168 2009-08-20  
<div class="quote_title">jianguang_qq 写道</div><div class="quote_div"><div class="quote_title">lifesinger 写道</div>
<div class="quote_div">
<div class="quote_title">
<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/"></a>clone168 写道</div>
<div class="quote_div">
<p><span>作者js功力确实不错,可惜俺有一个疑问(具体<span style="background-color: #ffffff;">见</span><span><span style="font-weight: normal;"><span style="text-decoration: none;"><span style="font-size: small;"><span style="color: #000000;"><span style="background-color: #ffffff;"><a class="quote_title" style="color: white; background-color: #108ac6;" title="js一个很奇怪的问题" href="http://clone168.iteye.com/blog/452290" target="_blank">js一个很奇怪的问题</a><span>),当我把“代码六”中的</span></span></span></span></span></span></span></span></p>
<p> </p>
很奇怪,不知道什么原因
<p> </p>
</div>
<p> </p>
<p>是因为 new Timer(id) 的内部机制里,请参考:<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/">http://lifesinger.org/blog/2009/08/new-funtion-secret/</a></p>
</div>
<p> </p>
<p> </p>
<p>lifesinger牛人,从内部机制来分析,分析的很细,让我学习了不少。从内部来分析,需要对内部非常了解。因此看起来比较困难。</p>
<p>方式A:</p>
<pre name="code" class="java">function Dog() {
alert(this.__proto__.name); // undefined
Dog.prototype.name = 2; //方式A (注意这里)
  alert(this.__proto__.name); // 2 (注意这里)
 }

var dog1 = (function(){
var o = {__proto__: Dog.prototype};
alert(Dog.prototype.name);// undefined
alert(o.__proto__.name); // undefined
Dog.apply(o);
alert(Dog.prototype.name) //2
alert(o.__proto__.name); //2
return o;
})()

alert(dog1.__proto__.name) // 2
alert(dog1.name) // 2</pre>
<p> 方式B:
</p>
<pre name="code" class="js">function Dog() {
alert(this.__proto__.name); // undefined
Dog.prototype = {name : 2}//方式B (注意这里)
  alert(this.__proto__.name); // undefined (注意这里)
}

var dog1 = (function(){
var o = {__proto__: Dog.prototype};
alert(Dog.prototype.name);// undefined
alert(o.__proto__.name); // undefined
Dog.apply(o);
alert(Dog.prototype.name) //2
alert(o.__proto__.name); //undefined
return o;
})()

alert(dog1.__proto__.name) // undefined
alert(dog1.name) // undefined</pre>
<p>化简后的问题:</p>
<pre name="code" class="js">function Base(){
Base.prototype.name = 2; //方式A (注意这里)
alert(this.a.name) //2(注意这里)
}
var o = {a : Base.prototype};
Base.apply(o);
alert(o.a.name);// 2(注意这里)

function Base2(){
Base2.prototype = {name : 2}; //方式B(注意这里)
alert(Base2.prototype.name) //2
alert(this.a.name) //undefined(注意这里)
}
var o2 = {a : Base2.prototype};
Base2.apply(o2);
alert(o2.a.name);// undefined(注意这里)</pre></div><br/>楼上例子简明易懂,赞一个
27 楼 jianguang_qq 2009-08-19  
<div class="quote_title">lifesinger 写道</div>
<div class="quote_div">
<div class="quote_title">
<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/"></a>clone168 写道</div>
<div class="quote_div">
<p><span>作者js功力确实不错,可惜俺有一个疑问(具体<span style="background-color: #ffffff;">见</span><span><span style="font-weight: normal;"><span style="text-decoration: none;"><span style="font-size: small;"><span style="color: #000000;"><span style="background-color: #ffffff;"><a class="quote_title" style="color: white; background-color: #108ac6;" title="js一个很奇怪的问题" href="http://clone168.iteye.com/blog/452290" target="_blank">js一个很奇怪的问题</a><span>),当我把“代码六”中的</span></span></span></span></span></span></span></span></p>
<p> </p>
很奇怪,不知道什么原因
<p> </p>
</div>
<p> </p>
<p>是因为 new Timer(id) 的内部机制里,请参考:<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/">http://lifesinger.org/blog/2009/08/new-funtion-secret/</a></p>
</div>
<p> </p>
<p> </p>
<p>lifesinger牛人,从内部机制来分析,分析的很细,让我学习了不少。从内部来分析,需要对内部非常了解。因此看起来比较困难。</p>
<p>方式A:</p>
<pre name="code" class="java">function Dog() {
alert(this.__proto__.name); // undefined
Dog.prototype.name = 2; //方式A (注意这里)
  alert(this.__proto__.name); // 2 (注意这里)
 }

var dog1 = (function(){
var o = {__proto__: Dog.prototype};
alert(Dog.prototype.name);// undefined
alert(o.__proto__.name); // undefined
Dog.apply(o);
alert(Dog.prototype.name) //2
alert(o.__proto__.name); //2
return o;
})()

alert(dog1.__proto__.name) // 2
alert(dog1.name) // 2</pre>
<p> 方式B:
</p>
<pre name="code" class="js">function Dog() {
alert(this.__proto__.name); // undefined
Dog.prototype = {name : 2}//方式B (注意这里)
  alert(this.__proto__.name); // undefined (注意这里)
}

var dog1 = (function(){
var o = {__proto__: Dog.prototype};
alert(Dog.prototype.name);// undefined
alert(o.__proto__.name); // undefined
Dog.apply(o);
alert(Dog.prototype.name) //2
alert(o.__proto__.name); //undefined
return o;
})()

alert(dog1.__proto__.name) // undefined
alert(dog1.name) // undefined</pre>
<p>化简后的问题:</p>
<pre name="code" class="js">function Base(){
Base.prototype.name = 2; //方式A (注意这里)
alert(this.a.name) //2(注意这里)
}
var o = {a : Base.prototype};
Base.apply(o);
alert(o.a.name);// 2(注意这里)

function Base2(){
Base2.prototype = {name : 2}; //方式B(注意这里)
alert(Base2.prototype.name) //2
alert(this.a.name) //undefined(注意这里)
}
var o2 = {a : Base2.prototype};
Base2.apply(o2);
alert(o2.a.name);// undefined(注意这里)</pre>
26 楼 clone168 2009-08-19  
<div class="quote_title">lifesinger 写道</div>
<div class="quote_div">
<div class="quote_title">
<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/"></a>clone168 写道</div>
<div class="quote_div">
<p><span>作者js功力确实不错,可惜俺有一个疑问(具体<span style="background-color: #ffffff;">见</span><span><span style="font-weight: normal;"><span style="text-decoration: none;"><span style="font-size: small;"><span style="color: #000000;"><span style="background-color: #ffffff;"><a class="quote_title" style="color: white; background-color: #108ac6;" title="js一个很奇怪的问题" href="http://clone168.iteye.com/blog/452290" target="_blank">js一个很奇怪的问题</a><span>),当我把“代码六”中的</span></span></span></span></span></span></span></span></p>
<p> </p>
很奇怪,不知道什么原因
<p> </p>
</div>
<p> </p>
<p>是因为 new Timer(id) 的内部机制里,请参考:<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/">http://lifesinger.org/blog/2009/08/new-funtion-secret/</a></p>
</div>
<p>射雕的文章我看了,只可惜自己还是感觉不太明白:</p>
<p>
</p>
<div class="quote_title">射雕 写道</div>
<div class="quote_div">// Dog.prototype = {constructor: Dog};<br>var o = {__proto__: Dog.prototype};<br>// 此时,o = {__proto__: {constructor: Dog}}<br>Dog.apply(o);<br>// 此时,Dog.prototype = {shout: function(){...}}<br>return o;<br>显然,运行 dog1.shout() 时,dog1 的确没有 shout 方法。</div>
 
25 楼 lifesinger 2009-08-19  
<div class="quote_title">
<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/"></a>clone168 写道</div>
<div class="quote_div">
<p><span>作者js功力确实不错,可惜俺有一个疑问(具体<span style="background-color: #ffffff;">见</span><span><span style="font-weight: normal;"><span style="text-decoration: none;"><span style="font-size: small;"><span style="color: #000000;"><span style="background-color: #ffffff;"><a class="quote_title" style="color: white; background-color: #108ac6;" title="js一个很奇怪的问题" href="http://clone168.iteye.com/blog/452290" target="_blank">js一个很奇怪的问题</a><span>),当我把“代码六”中的</span></span></span></span></span></span></span></span></p>
<p> </p>
很奇怪,不知道什么原因
<p> </p>
</div>
<p> </p>
<p>是因为 new Timer(id) 的内部机制里,请参考:<a href="http://lifesinger.org/blog/2009/08/new-funtion-secret/">http://lifesinger.org/blog/2009/08/new-funtion-secret/</a></p>
24 楼 lifesinger 2009-08-19  
02221021 写道
setTimeout的开销大一点
setInterval有可能线程阻塞
孰优孰劣还是要看具体情况吧


的确如此。
对于复杂页面,线程阻塞比内存开销更恐怖,作为一个良好的编码习惯,推荐多用setTimeout
23 楼 clone168 2009-08-19  
<p><span style="">作者js功力确实不错,可惜俺有一个疑问(具体<span style="background-color: #ffffff;">见</span><span style=""><span style="font-weight: normal;"><span style="text-decoration: none;"><span style="font-size: small;"><span style="color: #000000;"><span style="background-color: #ffffff;"><a class="quote_title" style="color: white; background-color: #108ac6;" title="js一个很奇怪的问题" href="http://clone168.iteye.com/blog/452290" target="_blank">js一个很奇怪的问题</a><span style="">),当我把“代码六”中的</span></span></span></span></span></span></span></span></p>
<p> </p>
<pre name="code" class="js">Timer.prototype = {   
    begin : function(count){   
        this.count = count;   
        this.show(this)();//注意这里不是Timer.show(this)();   
        this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();   
    },   
    show : function(obj){      
        return function(){   
            if(obj.count &lt; 0){   
                document.getElementById(obj.id).innerHTML = "over";   
                clearInterval(obj.timer);   
                return ;   
            }   
            document.getElementById(obj.id).innerHTML = obj.count;   
            obj.count--;   
        }   
    }    
}    </pre>
<p> </p>
<p> 放在Timer构造函数内部的话:</p>
<p> </p>
<pre name="code" class="js">function Timer(id){   
    this.id = id;   
    this.timer = null;   
    this.count = 0;   
    Timer.prototype = { 
        begin : function(count){   
            //alert(this); 
            this.count = count;   
            this.show(this)();//注意这里不是Timer.show(this)();   
            this.timer = setInterval(this.show(this),1000);//注意这里不是Timer.show(this)();   
        },   
        show : function(obj){      
            return function(){   
                if(obj.count &lt; 0){   
                    document.getElementById(obj.id).innerHTML = "over";   
                    clearInterval(obj.timer);   
                    return ;   
                }   
                document.getElementById(obj.id).innerHTML = obj.count;   
                obj.count--;   
            }   
        }   
    }; 
}  </pre>
<p> </p>
<p> <span style="font-family: Arial; line-height: 18px;"><span style="">在</span><span lang="EN-US">firebug</span><span style="">下面提示:“</span><span class="objectboxobjectbox-errormessagehastwistyhasbreakswitchopened"><span lang="EN-US">t1.begin is not a function</span></span><span style="">”这样的错误,<span style="font-family: Arial;"><span>而且,看到“代码七”就发现,都用</span><span lang="EN-US">Timer.prototype.begin</span><span>和</span><span lang="EN-US">Timer.prototype.show</span><span>就算写在里面也能运行:</span></span></span></span></p>
<p>
</p>
<pre name="code" class="js">function Timer(id){   
    this.id = id;   
    this.timer = null;   
    this.count = 0;   
    Timer.prototype.begin = function(count){   
        this.count = count;   
        this.show(this)();//主要这里不是Timer.show(this)();   
        this.timer = setInterval(this.show(this),1000);//主要这里不是Timer.show(this)();   
    }   
    Timer.prototype.show = function(obj){      
        return function(){   
            if(obj.count &lt; 0){   
                document.getElementById(obj.id).innerHTML = "over";   
                clearInterval(obj.timer);   
                return ;   
            }   
            document.getElementById(obj.id).innerHTML = obj.count;   
            obj.count--;   
        }   
    }    
}    </pre>
 很奇怪,不知道什么原因
<p> </p>
22 楼 02221021 2009-08-19  
setTimeout的开销大一点
setInterval有可能线程阻塞
孰优孰劣还是要看具体情况吧
21 楼 lifesinger 2009-08-19  
function Timer(id) {
    this.container = document.getElementById(id);
}

Timer.prototype = {

    constructor: Timer,

    begin: function(count) {
        var container = this.container;
        setTimeout(function() {
            container.innerHTML = count > 0 ? count-- : "over";
            if(count + 1) {
                setTimeout(arguments.callee, 1000);
            }
        }, 1000);
    }
    
};

new Timer("time1").begin(10);


也来一个,补充两点:

1. prototype 的 constructor 不要搞丢了
2. 用 setTimeout,比 setInterval 好
20 楼 flyfan 2009-08-18  
对这些js牛人佩服呀,另外zbm2001写得确实不错
19 楼 black.angel 2009-08-18  
我纯粹只是欣赏 zbm2001 对软件代码质量的控制能力和严谨的学习态度.赞一个.
18 楼 02221021 2009-08-17  
此回帖已被管理员和谐.
17 楼 Saito 2009-08-17  
茴香豆的"茴"字有多少种写法.. 突然想到说Java的singleton有多少种写法.

     js太灵活了. 以至于我无法驾驭..  不过支持剑光.
16 楼 zbm2001 2009-08-17  
引用

1 ,这2个想当然尔的理论是从一些书上看到的,比如月影的王者归来,月影做为我眼里这个理论的发源地,相信他会为此负责的.

你难道总是希望别人为你的代码负责?
只可惜宁愿迷信所谓某人、某书、某权威,也不愿写几行代码测试一下。

引用

……john resig大人也说他真正理解闭包花去了相当多的精力和时间.

既然你已知道john resig都花去了相当多的精力和时间才真正理解闭包,所以你应该明白我所说的——你的结论在这(真正理解闭包)之后再下吧:
引用

……
如果你一直坚持尝试利用闭包来简化你的开发(虽然可能曾经会饱受挫折),并结合着不断阅读直到完全理解下文,再来回顾上面的结论看看……


不过对于一个对某些结论连几行测试代码都懒的写,还声称自有别人为这些结论负责的程序员
——估计也不能指望比john resig花更多的的精力和时间了!
15 楼 02221021 2009-08-17  
此回帖已被管理员和谐.
14 楼 zbm2001 2009-08-17  
02221021 写道
补充3楼1点啊, 频繁操作dom节点确实非常不好,不过也许document.getElementById和document.getElementsByTagName是两个例外.大部分浏览器都对这2个方法做了优化.速度跟用引用来取相差无几.

这个想当然尔的理论从哪里来?
你随便一说,也不知道谁会受到误导,测试几个主流浏览器出个数据再说吧。

02221021 写道


1. 可能存在的内存泄露.

2. 让scope chains难以维护.

3. 程序可读性降低,闭包引起的bug经常叫人抓狂.

其实闭包不是个很神秘的东西,没有必要想法设法跟它扯上关系.不过楼主的研究精神狠赞一个.

如果你一直坚持尝试利用闭包来简化你的开发(虽然可能曾经会饱受挫折),并结合着不断阅读直到完全理解下文,再来回顾上面的结论看看……
中译文:
http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html
原文:
http://www.jibbering.com/faq/faq_notes/closures.html
13 楼 jianguang_qq 2009-08-16  
sw1982 写道
呵呵。剑光也搬到javaeye了?

是啊,发现javaeye质量比csdn高好多哦

相关推荐

    javascript实现计时器

    "JavaScript实现计时器"这个主题涉及到JavaScript编程中的一个常见任务:创建一个可以随着时间流逝更新的计时器。计时器在各种网页应用中都有广泛的应用,如倒计时、实时显示时间等。下面我们将深入探讨如何使用...

    js计时器数字卡片翻转秒表计时器网页特效

    "js计时器数字卡片翻转秒表计时器网页特效"就是一个利用JavaScript实现的动态计时功能,它结合了数字卡片翻转的效果,使得秒表计时更为直观且具有视觉吸引力。这种效果常见于体育竞赛、健身应用或者任何需要实时计时...

    css3圆形进度条时分秒计时器js特效

    总结,这款“css3圆形进度条时分秒计时器js特效”充分利用了CSS3的高级特性,结合JavaScript的时间管理和DOM操作,实现了动态的、可视化的计时功能。这样的特效不仅可以提升用户体验,也可以在各种应用场景中增加...

    【JavaScript源代码】JS实现一个秒表计时器.docx

    在JavaScript中,实现一个秒表计时器涉及到定时器(setTimeout和setInterval)以及DOM操作。下面我们将详细探讨这些知识点: 1. **定时器:** - `setInterval` 函数用于每隔一定时间执行一次指定的函数。在这个...

    JS CSS3实现苹果iwatch计时器.zip

    在本项目"JS CSS3实现苹果iwatch计时器.zip"中,我们主要探讨的是如何使用JavaScript(JS)和CSS3技术来模拟苹果iWatch的计时器功能,包括开始、暂停以及重置操作,并能记录计时次数。这个项目对于前端开发者来说,...

    js css3圆形的时分秒计时器动画特效

    本文将详细探讨如何利用这两者来实现一个圆形的时分秒计时器动画特效。 首先,我们需要了解JavaScript(JS)的基础。JavaScript是一种解释型的、面向对象的、弱类型的脚本语言,常用于网页和网络应用开发。它能够...

    js计时器 (脚本语言)

    JavaScript(简称JS)是网页开发中的重要脚本语言,它提供了丰富的功能,其中之一就是计时器功能。在JavaScript中,计时器常用于实现动画效果、执行定时任务、或者跟踪时间流逝等。本文将深入探讨JavaScript计时器的...

    js实现简易计时器

    自己实现的简单的倒计时器,发现网上关于这方面的代码有...我自己用js手写了一个分享给大家,界面比较简洁,后面会再写一个比较酷炫的。如果没有积分还想下载的小伙伴可以加qq邮箱联系我,我发给你:1343121616@qq.com

    计时器实现

    总结来说,计时器在各种编程语言和应用领域都有着广泛的应用,其实现方式多种多样,从简单的循环检查到复杂的事件驱动,都需要根据具体需求和环境来选择合适的方法。理解并掌握计时器的原理和实现技巧,对于提升软件...

    javascript 秒表计时器实现代码

    接下来,我们将深入探讨如何使用JavaScript来实现一个基本的秒表计时器功能。在上述提供的代码示例中,我们能够看到创建一个秒表计时器所依赖的关键元素和方法。 首先是HTML部分,这是用户界面的基础。在`&lt;body&gt;`...

    javascript秒表计时器

    以下是一个简单的JavaScript秒表计时器的实现: ```javascript let startTime = null; let elapsedTime = 0; let timerInterval = null; function startTimer() { startTime = new Date(); timerInterval = ...

    简单清新的纯JS实现的计时特效电子计时效果源码下载

    总的来说,这个"简单清新的纯JS实现的计时特效电子计时效果"源码提供了一个学习和实践JavaScript计时器功能的平台。通过理解和研究源码,开发者不仅可以掌握基本的计时器实现,还能进一步了解JavaScript与DOM的交互...

    javascript 实现网页 倒计时 代码

    本篇文章将详细介绍如何利用JavaScript编写一个网页倒计时功能,并结合提供的`index.html`和`js`文件进行解析。 首先,我们需要理解JavaScript中的时间处理。JavaScript使用`Date`对象来表示日期和时间,它提供了...

    js实现倒计时

    javascript实现倒计时

    多功能计时器-倒计时器

    "多功能计时器-倒计时器"这款应用程序,正如其标题所示,旨在提供一种高效且灵活的计时解决方案,适应多种场景的需求。 首先,我们来详细探讨倒计时器的核心功能。倒计时器是一种能够从预设时间开始向零倒数的计时...

    JS 系列计时器资料.rar

    "JS系列计时器资料.rar"这个压缩包包含了关于JavaScript计时器的详细文档,名为"5.JS计时器.doc"。以下将深入探讨JavaScript中的计时器机制及其应用。 1. **setTimeout()和setInterval()** - `setTimeout()`: 这个...

    理想Web倒计时器的设计与实现

    通过上述代码实现,我们能够构建一个既能够在不同客户端间保持同步,又具备防刷新、防关闭和自校正功能的理想Web倒计时器。这种方式不仅提高了用户体验,也为Web开发者提供了更为灵活可靠的解决方案。

    jQuery实现的倒计时器

    在这个项目中,我们将深入探讨如何使用jQuery实现一个倒计时器。 首先,我们需要理解jQuery的基本使用。jQuery通过简洁的语法来处理DOM操作、事件处理和动画效果。例如,我们可以使用`$`符号来选择元素,然后对这些...

    Android计时器实现

    本文将深入探讨如何在Android中实现计时器功能,主要以`HLQCountDownTimer`为例,这是一个自定义的倒计时计时器类。 ### 一、Android计时器基础 在Android中,有多种计时器实现方式,包括`java.util.Timer`、`...

    djs.rar_DJS哪里的时间_djs_倒计时_倒计时器_倒计时计时器

    本文将详细探讨“DJS倒计时器”,一种小巧而实用的计时工具,以及它的功能、实现原理和使用方法。 首先,DJS倒计时器的核心功能在于设定并显示一个特定时间点前的剩余时间。用户可以根据自己的需求,设定一个未来的...

Global site tag (gtag.js) - Google Analytics