论坛首页 Web前端技术论坛

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

浏览 15706 次
精华帖 (7) :: 良好帖 (5) :: 新手帖 (3) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-18  
对这些js牛人佩服呀,另外zbm2001写得确实不错
0 请登录后投票
   发表时间: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 好
0 请登录后投票
   发表时间:2009-08-19  
setTimeout的开销大一点
setInterval有可能线程阻塞
孰优孰劣还是要看具体情况吧
0 请登录后投票
   发表时间:2009-08-19  

作者js功力确实不错,可惜俺有一个疑问(具体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 < 0){    
                document.getElementById(obj.id).innerHTML = "over";    
                clearInterval(obj.timer);    
                return ;    
            }    
            document.getElementById(obj.id).innerHTML = obj.count;    
            obj.count--;    
        }    
    }     
}    

 

 放在Timer构造函数内部的话:

 

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 < 0){    
                    document.getElementById(obj.id).innerHTML = "over";    
                    clearInterval(obj.timer);    
                    return ;    
                }    
                document.getElementById(obj.id).innerHTML = obj.count;    
                obj.count--;    
            }    
        }    
    };  
}  

 

 firebug下面提示:“t1.begin is not a function”这样的错误,而且,看到“代码七”就发现,都用Timer.prototype.beginTimer.prototype.show就算写在里面也能运行:

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--;    
        }    
    }     
}    
 很奇怪,不知道什么原因

 

0 请登录后投票
   发表时间:2009-08-19  
02221021 写道
setTimeout的开销大一点
setInterval有可能线程阻塞
孰优孰劣还是要看具体情况吧


的确如此。
对于复杂页面,线程阻塞比内存开销更恐怖,作为一个良好的编码习惯,推荐多用setTimeout
0 请登录后投票
   发表时间:2009-08-19   最后修改:2009-08-19
clone168 写道

作者js功力确实不错,可惜俺有一个疑问(具体js一个很奇怪的问题),当我把“代码六”中的

 

很奇怪,不知道什么原因

 

 

是因为 new Timer(id) 的内部机制里,请参考:http://lifesinger.org/blog/2009/08/new-funtion-secret/

0 请登录后投票
   发表时间:2009-08-19  
lifesinger 写道
clone168 写道

作者js功力确实不错,可惜俺有一个疑问(具体js一个很奇怪的问题),当我把“代码六”中的

 

很奇怪,不知道什么原因

 

 

是因为 new Timer(id) 的内部机制里,请参考:http://lifesinger.org/blog/2009/08/new-funtion-secret/

射雕的文章我看了,只可惜自己还是感觉不太明白:

射雕 写道
// Dog.prototype = {constructor: Dog};
var o = {__proto__: Dog.prototype};
// 此时,o = {__proto__: {constructor: Dog}}
Dog.apply(o);
// 此时,Dog.prototype = {shout: function(){...}}
return o;
显然,运行 dog1.shout() 时,dog1 的确没有 shout 方法。
 
0 请登录后投票
   发表时间:2009-08-19   最后修改:2009-08-20
lifesinger 写道
clone168 写道

作者js功力确实不错,可惜俺有一个疑问(具体js一个很奇怪的问题),当我把“代码六”中的

 

很奇怪,不知道什么原因

 

 

是因为 new Timer(id) 的内部机制里,请参考:http://lifesinger.org/blog/2009/08/new-funtion-secret/

 

 

lifesinger牛人,从内部机制来分析,分析的很细,让我学习了不少。从内部来分析,需要对内部非常了解。因此看起来比较困难。

方式A:

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

 方式B:

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

化简后的问题:

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(注意这里)
0 请登录后投票
   发表时间:2009-08-20  
jianguang_qq 写道
lifesinger 写道
clone168 写道

作者js功力确实不错,可惜俺有一个疑问(具体js一个很奇怪的问题),当我把“代码六”中的

 

很奇怪,不知道什么原因

 

 

是因为 new Timer(id) 的内部机制里,请参考:http://lifesinger.org/blog/2009/08/new-funtion-secret/

 

 

lifesinger牛人,从内部机制来分析,分析的很细,让我学习了不少。从内部来分析,需要对内部非常了解。因此看起来比较困难。

方式A:

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

 方式B:

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

化简后的问题:

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(注意这里)

楼上例子简明易懂,赞一个
0 请登录后投票
   发表时间:2009-08-24   最后修改: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() {

};
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics