`
clone168
  • 浏览: 7422 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

js一个很奇怪的问题

阅读更多

 

前几天在javaeye上看到一篇帖子:JS优化系列】从一个计时器的写法探讨js多种实现方式的优劣,感觉楼主确实厉害,一个计时器能有那么多优雅的写法,而且全部是用的面向对象的思想,我花了整整一天时间把那些写法全部消化,也看了那些留下的评论,发现javaeye上面确实人才辈出,难怪我师兄把博客都从csdn搬到javaeye了。这里我把我发现的一个很奇怪的问题贴出来,希望有大牛能帮我解惑哈

帖子里的“代码六”是这样的:

 

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--;  
        }  
    }   
}  

 

这份代码没有任何问题,运行结果一切正常,可是,当我把“Timer.prototype={”这一行以及后面的移到Timer构造函数内部的时候,却发现在firebug下面提示:“t1.begin is not a function”这样的错误,代码如下:

 

<body>  
<div id="time1">time1</div>  
<div id="time2">time2</div>  
</body>  
<script>  
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--;  
			}  
		}  
	};
}

		
t1 = new Timer("time1");  
t2 = new Timer("time2");

t1.begin(10);  
t2.begin(10);  
</script>

 而且,看到“代码七”就发现,都用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--;  
        }  
    }   
}  
 我不明白为什么会这么诡异,希望俺帖能起到抛砖引玉的效果。期待大牛们的精彩解答!

 

 

 

1
0
分享到:
评论
1 楼 szcjlssx 2009-10-03  
这个问题在学JS的面向对象时就应该讲过了
事实上是这个问题,很简单
function Class() {
    //空的
}
Class.prototype.method=function () {
    alert("继承的方法");
};
var c = new Class();
c.method();//正常

应该记得,prototype方式的继承,如果要继承另一个类,写法是这样的
Class.prootype=new Parent();//Class类继承Parent父类
//注意这里是直接赋值去一个对象(new Parent());但这样有个问题,往下
function Class() {
    //空的
}
function Parent() {
    this.attr=123;
}
Class.prototype=new Parent();//继承Parent
var c = new Class();
alert(c.attr);//正常,123

如果换个方式写
function Class() {
    //空的
}
function Parent() {
    this.attr=123;
}
var c = new Class();
Class.prototype=new Parent();//已经实例化过了,再继承Parent
alert(c.attr);//没有了

因为Class.prototype被替换成了一个新对象,要让实例c继承Parent的attr属性,必须写成
//要么先继承,再实例化,要么就用克隆属性的方法
Class.prototype.attr=(new Parent()).attr;

查看你的代码,写的是
Timer.prototype = {  };
//但将其放在构造函数内部时,注意 ,在这行之上,已经有了this了,证明已经实例化了
//这时再去用这种直接将prototype重置为另一个对象的继承方法,就不行了

最后,对于这个贴子,我也回了一个代码,没有用构造函数,你可以去看看,(嗯,再打个广告,留个联系方法 Q-Q-群 AjaxLife 57847622,欢迎来讨论交流)
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    一个奇怪的问题使用ajax提交必须alert才能赋值

    然而,当你遇到"一个奇怪的问题使用ajax提交必须alert才能赋值"这样的问题时,这通常涉及到异步编程的特性以及JavaScript执行的顺序。 在描述中提到的情况,开发者尝试将AJAX请求的返回值赋给一个变量,但发现无论...

    解决JS浮点数(小数)计算加减乘除的BUG

    这个问题是许多开发者在编写JavaScript代码时可能遇到的一个常见陷阱。本文将深入探讨这个问题,并提供解决方案。 首先,我们需要理解JavaScript中的浮点数是如何存储的。JavaScript使用IEEE 754标准来表示浮点数,...

    Baseline.js, 一个简单的jQuery插件,用于恢复由奇怪图像大小抛出的垂直基线.zip

    Baseline.js, 一个简单的jQuery插件,用于恢复由奇怪图像大小抛出的垂直基线 Baseline.jsBaseline.js 是一个简单的jquery/zepto插件,用于恢复由奇数图像大小抛出的基线。像这样调用插件,将基线的高度作为变量传递...

    解决ajax返回innerHTML中javascript不能运行问题

    在实际应用中,我们经常会遇到使用 Ajax 返回某一个网页的内容到模板页面的某一个 `&lt;div&gt;` 标签中显示的操作。如果返回的值仅仅是文本类数据,不会影响模板页面的功能,但是如果返回的数据包括 JavaScript,那么直接...

    JavaScript_一个脚本的集合,描述了编程语言的奇怪特性.zip

    3. `eval()`:这是一个危险的方法,因为它可以执行字符串形式的JavaScript代码,可能导致安全问题和性能下降。 4. `delete`操作符:虽然可以删除对象的属性,但不能删除数组的元素,也不能删除方法。 5. `...

    在一个js文件里远程调用jquery.js会在ie8下的一个奇怪问题

    解决这个问题的一种常见方法是在jQuery库的URL后面添加一个时间戳或者随机字符串作为查询参数,这样每次刷新时URL都会改变,浏览器会强制重新下载资源,例如: ```javascript include(...

    javascript中一些数据类型以及奇怪的特性

    JavaScript中的一些奇怪之处在于,它将Number视为一个连续的数值范围,包括正无穷和负无穷。 - **String**:字符串,由一串字符组成,可以使用单引号或双引号定义。 - **Symbol**(ES6新增):唯一的标识符,用于...

    奇怪的大冒险源码

    同时,这也是一个很好的实践机会,将理论知识应用于实际项目,锻炼解决问题的能力。对于初学者,这是一个很好的起点,而对于有一定经验的开发者,这则是一个探索新思路和提高代码质量的好途径。

    field-js:一种非常奇怪的计算语言(设计尖峰)

    它可能是JavaScript的一个扩展或变形,利用JavaScript的动态特性和生态系统,构建出一种不同寻常的编程体验。JavaScript作为Web开发的基石,有着广泛的社区支持和丰富的库资源,使得任何基于JavaScript的新语言都有...

    JS 判断是否是数字

    JavaScript(简称JS)是一种广泛用于Web开发的轻量级脚本语言,它的功能强大且灵活,其中一项常见的任务就是判断一个变量是否为数字。在JS中,数字可以是整数或浮点数,甚至可以是正无穷、负无穷或者NaN(非数字)。...

    myalpine:一些奇怪的alpine.js克隆

    "myalpine:一些奇怪的alpine.js克隆" 这个标题表明,这是一个关于Alpine.js的项目,而且是其某种形式的克隆或变体,可能具有独特的特性和功能。"奇怪的"一词暗示这个克隆版可能包含了非传统或者不常见的实现方式,...

    大名鼎鼎SWFUpload- Flash+JS 上传

     SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而超越传统标签的文件上传模式。 [编辑本段]SWFUpload的主要特点  * 可以...

    基于nodejs 的博客园爬虫项目(javascript)

    当把页面内容抓回来后,一般不会直接分析,而是用一定策略存下来,个人觉得更好的架构应该是把分析和抓取分离,更加松散,每个环节出了问题能够隔离另外一个环节可能出现的问题,好排查也好更新发布。 那么存文件...

    js常见经典面试题汇总

    根据ECMAScript规范,`typeof null`的结果是`"object"`,这是一个历史遗留问题。`null`的初衷是为了表示一个空的对象指针,但由于历史原因导致了这种奇怪的行为。 #### 17. 事件冒泡与事件捕获原理 - **事件冒泡**...

    strange_attractors:奇怪吸引子的Threejs实现

    "奇怪吸引子"是混沌理论中的一个重要概念,它在数学、物理和计算机科学等领域都有广泛的应用。...同时,这也是一个很好的机会去探索数学、艺术和编程之间的交集,以及如何将抽象概念转化为引人入胜的交互体验。

    transform.js:Transform.js 是一个用于将 3D 点投影到 2D 空间的小型 JavaScript 库

    转换.js Transform.js 是一个用于将 3D 点投影到 2D 空间的小型 JavaScript 库。 Transform.js不是3D 渲染器。 不要尝试渲染网格,因为如果您希望深度映射起作用,您会得到奇怪的结果。 线和点都很好。

Global site tag (gtag.js) - Google Analytics