- 浏览: 965031 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
sscsacdsadcsd:
mike8625 写道react还要自己的一些标签 还得编译 ...
对于React体系的一点想法 -
mike8625:
说的都是给大公司听的,国内很多还是小公司,做个小项目, 说实话 ...
关于国内前端和JS技术发展的乱想 -
mike8625:
react还要自己的一些标签 还得编译 编译吧浏览器端说还慢 ...
对于React体系的一点想法 -
u012814086:
下意识想到了Golang
JavaScript语句后应该加分号么? -
xueduanyang:
我是水羊,年轻的时候觉得只要有好斧子就能做成好产品,各种产品都 ...
关于国内前端和JS技术发展的乱想
最近,小麦提出了一个疑惑:
这里刨去其实无关的 if 语句,可以把问题简化成这样的形式:
按理应该输出“1”,但是在IE中输出“undefined”。
而将两段script合并在一起
或者先加上一句“x = xxx”的赋值语句
输出结果就是正常的“1”。
这神奇的现象到底是为什么涅?
Dr. Hax告诉你:这是因为IE下的全局变量存在DID。
我们知道创建global变量有三种方式,一种是直接用名字:
x = 1
alert(x)
一种是用var声明:
var x = 1
alert(x)
除了明确进行了变量声明外,主要区别是,var x声明所创建的x是不能被delete的。
还有一种呢,就是通过global对象的属性,即window.x或window["x"]的赋值来创建:
window.x = 1
alert(window.x)
在创建完成之后,存取全局变量就是两种方式,一种是直接通过名字,如:
if(x == 1) x = 2
另一种则通过global对象的属性来存取,如:
if (window["x"] == 1) window.x = 2
按照BE大神的设计,全局变量的三种创建方式本应是三位一体的,两种存取方式也应是等同的,但是在M$IE中,其window.x的实现导致了DID问题——根据Dr. Hax的观察,在IE中全局变量分裂出了至少两种变量格。
我们来看看临床症状。
翻译到我们的语境则是:
以上代码可正常执行。但是如果把第二行的注释去掉,可以观察到在执行 alert(x) 时报出一个“Out of memory”的错误!其后你也将不能对x或者window.x做任何事情。
这短短的代码怎么能out of memory呢——显然这里产生了一个空指针(“遗失引用”)错误!
让我们进行成因分析。
转换一下语境:
为什么会这样?大体是因为JScript引擎的设计与IE DOM对接的缺陷所导致。
我们也可以从另一个方面来观察这个问题——我们来做一个性能力测试:
结果如下:
这个性能力测试告诉我们:
一、无论以何种方式创建全局变量,访问window.x总是比直接访问x要慢许多。访问window.x慢,这还是容易理解的。因为window.x实际上是DOM调用,可理解成被转换为node.getAttribute('x')。而直接访问x,则很可能做了不同的处理(比如也许省略了跨域安全检查)。
二、“x = 0”和“var x = 0”所创建的全局变量,存取性能上没有什么区别,而“window.x = 0”则差很多。这说明在创建全局变量时,前者和后者的存储方式很可能是完全不同的。
以上这两点,都完全符合Dr. Hax在临床症状中所描述的“……拥有各自操作模式和存储”。
由于无法进行病理解剖(没有IE和JScript引擎的源码),我们无法搞清楚所有细节,但是我们可以推断出个大概:
1. JScript引擎当然可以独立使用,而不依赖于DOM。在这样一种情况下,它本身就要处理全局变量的问题——譬如所有built-in的那些方法和对象。当引擎被嵌入到IE中时,就将JScript引擎的Global对象和DOM的window对象连接起来,而window对象,如同所有DOM对象一样,能够以expando属性方式保存额外的属性。这样就有了两个变量格,一个是基于JScript引擎内建的全局变量机制,一个是基于DOM的expando机制。
2. 对于x的存取和对于window.x的存取,前者是对于x这个引用的存取,而后者是对于window这个引用上进行x属性的存取。注意到这一区别,有助于理解下面的分析。
3. 以“x = xxx”方式新建全局变量时(前提是之前不存在任何形式的x引用),引擎并不会将x作为window的expando属性保存,而是按照JScript引擎的内建方式保存,并建立指向内部存储的x引用。内建方式是很高效的,比expando属性存取要快20倍以上。
上述判断,由DOM中的 document.expando 特性也可以佐证。当 document.expando=false 之后,你将不能使用 window.x = xxx 的方式新建全局变量,但是仍然可以用 x = xxx / var x = xxx 。
4. 在访问window.x时,如果已经有按照内建方式建立的x,则进行window.x到x的绑定,即产生一个指针指向内建方式创建的x,然后就凭借此指针来进行存取操作。然而在这里IE的开发者忘记了x引用可能被delete的情况,在x被delete之后,指针就失效了,从而导致之前的“Out of memory”错误。
5. 在对window.x进行赋值时,如果不存在按照内建方式保存的x,则会以window的expando属性方式保存(如果允许expando的话)。
6. 而在访问x时,如果没有按照内建方式建立的x引用,则检查引擎所连接的window对象上是否有x,即window上是否有expando。如果有,就建立x引用并指向window上的expando。如果没有,就扔出TypeError(按照标准其实应该扔出ReferenceError)。
7. 那么为什么在以expando方式建立变量后,存取window.x比存取x慢呢?
老实说,这个问题很难回答,只能大胆猜想一下:
存取window.x的步骤:
a. JScript引擎调用DOM对象存取属性的方法,假设记做 DOM::Window.get/setAttribute("x")
b. DOM::Window.get/setAttribute()方法先询问JScript引擎是否已经有内建全局变量x,假设记做 JScript::Global.hasProperty("x")
c. JScript::Global.hasProperty("x")返回false
d. 于是DOM::Window.get/setAttribute()方法存取expando属性,假设记做 DOM::Window.get/setExpando("x")
e. 将结果返回给JScript引擎
存取x的步骤:
a. JScript引擎查找是否存在x引用
b. JScript引擎根据x引用调用DOM::Window.get/setExpando("x")
c. DOM::Window.get/setExpando("x")返回结果给JScript引擎
根据上述猜想,存取window.x,是JScript调用DOM,DOM再回调JScript;而存取x,则只有JScript调用DOM。这就是性能差大概一倍的原因。
好了,绕了一大圈之后,我们来解释一下最初的代码为什么会有这样的结果。
这段代码会先以expando方式创建x。而后var x声明所进行的初始化操作,并不依赖于DOM,所以不会检测是否存在expando。道理上说应该检测,但是由于罹患DID,恰好此处JScript引擎并没有检测expando,而只会检测内建存储。并不存在内建的x,所以x引用就被重新初始化了,而且这次是以内建方式建立的。
而合并在一起后
var x声明会被提前,所以会以内建方式创建。执行 window.x = 1 时,已经有了内建的x,所以会建立到内建x的绑定,并对其赋值,而不会以expando方式保存。
先加上一句 x = xxx 的赋值语句
也会以内建方式创建x。这样之后的var x就不会重新初始化了。
最后说说治疗方案。
换到我们的语境下:
当然,我们有些简单的应对之道。
1. 不用全局变量,不折腾window对象。
从编程上说,使用全局变量不是一个好习惯。从JS效率而言,全局变量效率比局部变量要低许多。再加上IE独有的DID症,咱能不用就不用吧!
2. 如果一定要用全局变量,坚持直来直去,不折腾window对象。
也就是只用 var x 的方式。效率最高,也避免了DID症的可能发作。
3. 宁可折腾DOM元素,也不折腾window对象。
动态变量名,即window[name]之类的,可用一个 var container={name:value} 来替代,或者最不济的情形,你存到一个DOM元素上也好!
一样expando,DOM元素相比window,有个重要优点是有clearAttributes()方法可以清空所有属性(相当于delete操作),或者更快捷的方法是用parent.innerHTML或node.outerHTML直接清空。
或许你认为清空expando不重要,大谬!不信,你写个脚本给DOM元素上加10万个expando属性,然后按一次刷新看看。
附:DID疑难案例
在IE下输出什么?恢复被注释掉的第三行代码后呢?
答案请自己动手试验。
PS. 钻研DID多年的Dr. Hax还透露,实际上IE全局变量的DID不仅有两个变量格,实际上还有第三个变量格!你猜到了吗?欢迎留言竞猜。
刚试了下,悲剧得还没治好
“ body=1;”是个什么操作呢?比较奇怪!这肯定会报错啊,赋值也不是直接给对象赋吧。
我还是选C,看看《ajax实战》吧~另外,签名是签Dr. hax呢,还是签真实姓名呢?我拿去炫耀一下去~
站内留言地址,我邮寄给你,呵呵。
Army 写道
猜一下,难道是ie里对dom节点的id直接引用?中!发奖品了。。。奖品选项如下:A. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进午餐B. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进晚餐C. 获得由Dr. Hax签名的《Ajax实战:实例详解》一本D. 获得没有Dr. Hax签名的《Ajax实战:实例详解》一本
吃惊,我居然猜对了!
我住在上海南站附近,接近闵行区,张江的话太远了……
我还是选C,看看《ajax实战》吧~另外,签名是签Dr. hax呢,还是签真实姓名呢?我拿去炫耀一下去~
猜一下,难道是ie里对dom节点的id直接引用?
中!
发奖品了。。。奖品选项如下:
A. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进午餐
B. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进晚餐
C. 获得由Dr. Hax签名的《Ajax实战:实例详解》一本
D. 获得没有Dr. Hax签名的《Ajax实战:实例详解》一本
IE的分裂症还包括:window.clearInterval能重写,clearInterval不能重写.所有以内建方式建立的window方法的引用都不能重写和删除.是否这是第三个变量格?
不是的。要构成“变量格”必须满足Dr. Hax定义的条件:拥有各自操作模式和存储。
其中的关键是一个全局变量引用的目标到底是指向哪里。第三种变量格其实(在早期脚本里)很常见的。
sorry,Hax,好久没联系。
我不知道我问你要过MSN没?加我一下吧。我是小麦。
加过了,不过我99%时候不在线。。。
小麦 写道
最后介绍一个我也搞不明白的问题:
在HTML文档里写上这段代码:
<script type="text/javascript">
window['a'] = 'Hi';
</script>
<script type="text/javascript" src="out.js"></script>
<script type="text/javascript">
alert(a);
</script>
然后在out.js里写上这句:
if(false) {
var a = 'Hello';
}
然后用FF和IE6分别运行,看看你得到什么。
在FF里会弹出“Hi”,但是在IE6中,会得到“undefined”。
很神奇吧?按语法,无论如何,a都不可能是undefined。但是IE6里就会。
如果把两个语句都写在同一个文件里,就不会有这个情况。
如果把out.js里改成window.a,或者把前一个改成var a,也不会有这个情况。
如果把out.js里的var a移到if语句之外,或是把if的条件改为true,也不会有这个情况。
在HTML文档里写上这段代码:
<script type="text/javascript">
window['a'] = 'Hi';
</script>
<script type="text/javascript" src="out.js"></script>
<script type="text/javascript">
alert(a);
</script>
然后在out.js里写上这句:
if(false) {
var a = 'Hello';
}
然后用FF和IE6分别运行,看看你得到什么。
在FF里会弹出“Hi”,但是在IE6中,会得到“undefined”。
很神奇吧?按语法,无论如何,a都不可能是undefined。但是IE6里就会。
如果把两个语句都写在同一个文件里,就不会有这个情况。
如果把out.js里改成window.a,或者把前一个改成var a,也不会有这个情况。
如果把out.js里的var a移到if语句之外,或是把if的条件改为true,也不会有这个情况。
这里刨去其实无关的 if 语句,可以把问题简化成这样的形式:
<script> window.x = 1 </script> <script> var x alert(x) </script>
按理应该输出“1”,但是在IE中输出“undefined”。
而将两段script合并在一起
<script> window.x = 1 var x alert(x) </script>
或者先加上一句“x = xxx”的赋值语句
<script> x = null window.x = 1 </script> <script> var x alert(x) </script>
输出结果就是正常的“1”。
这神奇的现象到底是为什么涅?
Dr. Hax告诉你:这是因为IE下的全局变量存在DID。
Dr. Hax 写道
所谓DID,就是Dissociative identity disorder,译成中文就是“解离性自我认同紊乱”,放到人的身上,就是解離性人格疾患,即俗称“多重人格”、“人格分裂”是也。
我们知道创建global变量有三种方式,一种是直接用名字:
x = 1
alert(x)
一种是用var声明:
var x = 1
alert(x)
除了明确进行了变量声明外,主要区别是,var x声明所创建的x是不能被delete的。
x = 1 alert(delete x) // true var y = 1 alert(delete y) // false
还有一种呢,就是通过global对象的属性,即window.x或window["x"]的赋值来创建:
window.x = 1
alert(window.x)
在创建完成之后,存取全局变量就是两种方式,一种是直接通过名字,如:
if(x == 1) x = 2
另一种则通过global对象的属性来存取,如:
if (window["x"] == 1) window.x = 2
按照BE大神的设计,全局变量的三种创建方式本应是三位一体的,两种存取方式也应是等同的,但是在M$IE中,其window.x的实现导致了DID问题——根据Dr. Hax的观察,在IE中全局变量分裂出了至少两种变量格。
我们来看看临床症状。
维基百科 写道
多重人格患者的每一個人格都是穩定、發展完整、擁有各別思考模式和記憶的。……分裂出的人格之間知道彼此的存在,也有一些情況,人格之間並沒有察覺彼此的存在,這會導致嚴重的「遺失時間」現象。
翻译到我们的语境则是:
Dr. Hax 写道
IE下的每一种全局变量格都是稳定、开发完整、拥有各自操作模式和存储的。……分裂的变量格之间知道彼此的存在(因此,通常来说,无论用哪种方式存取,结果是一致的),但也有一些情况,它们之间没有察觉彼此的存在,这会导致严重的“遗失引用”现象。
x = {} // window.x alert(x) alert(delete x) try { alert(x) } catch(e) { alert(e.name + ":" + e.description) }
以上代码可正常执行。但是如果把第二行的注释去掉,可以观察到在执行 alert(x) 时报出一个“Out of memory”的错误!其后你也将不能对x或者window.x做任何事情。
这短短的代码怎么能out of memory呢——显然这里产生了一个空指针(“遗失引用”)错误!
让我们进行成因分析。
维基百科 写道
多重人格的產生與童年創傷有密切相關,尤其是性侵害。患者的男女比(1:9)可以作為佐證,這或許是女孩比男孩易受到性侵害的緣故。當受到難以應付的衝擊時,患者以「放空」的方式,以達到「這件事不是發生在我身上」的感覺,這對長期受到嚴重傷害的人(如近親相姦)來說,或許是必要的。
转换一下语境:
Dr. Hax 写道
多重变量格的产生与最初设计的bug有密切相关,尤其是对接的bug。开源软件和私有软件出现对接问题的比例(0:1?)可以作为佐证,这或许是私有软件(因不遵循标准)比开源软件更多受到对接问题困扰的缘故。当受到难以应付的调用时,问题软件以“out of memory”的方式,以达到“这件事不在我的记忆体中”的感觉,这对长期受到严重自大症困扰的公司(如开发者)来说,或许是必然的。
为什么会这样?大体是因为JScript引擎的设计与IE DOM对接的缺陷所导致。
我们也可以从另一个方面来观察这个问题——我们来做一个性能力测试:
var size = 1000000 x = 0 // var x = 0 // window.x = 0 var code = new Array(size + 1).join('x;') // var code = new Array(size + 1).join('x=0;') // var code = new Array(size + 1).join('window.x;') // var code = new Array(size + 1).join('window.x=0;') var f = new Function(code) var start = new Date() f() alert(new Date - start)
结果如下:
x x= window.x window.x= x = 0 156 172 3187 3469 var x = 0 156 172 3281 3422 window.x = 0 1516 1906 3297 3422
这个性能力测试告诉我们:
一、无论以何种方式创建全局变量,访问window.x总是比直接访问x要慢许多。访问window.x慢,这还是容易理解的。因为window.x实际上是DOM调用,可理解成被转换为node.getAttribute('x')。而直接访问x,则很可能做了不同的处理(比如也许省略了跨域安全检查)。
二、“x = 0”和“var x = 0”所创建的全局变量,存取性能上没有什么区别,而“window.x = 0”则差很多。这说明在创建全局变量时,前者和后者的存储方式很可能是完全不同的。
以上这两点,都完全符合Dr. Hax在临床症状中所描述的“……拥有各自操作模式和存储”。
由于无法进行病理解剖(没有IE和JScript引擎的源码),我们无法搞清楚所有细节,但是我们可以推断出个大概:
1. JScript引擎当然可以独立使用,而不依赖于DOM。在这样一种情况下,它本身就要处理全局变量的问题——譬如所有built-in的那些方法和对象。当引擎被嵌入到IE中时,就将JScript引擎的Global对象和DOM的window对象连接起来,而window对象,如同所有DOM对象一样,能够以expando属性方式保存额外的属性。这样就有了两个变量格,一个是基于JScript引擎内建的全局变量机制,一个是基于DOM的expando机制。
2. 对于x的存取和对于window.x的存取,前者是对于x这个引用的存取,而后者是对于window这个引用上进行x属性的存取。注意到这一区别,有助于理解下面的分析。
3. 以“x = xxx”方式新建全局变量时(前提是之前不存在任何形式的x引用),引擎并不会将x作为window的expando属性保存,而是按照JScript引擎的内建方式保存,并建立指向内部存储的x引用。内建方式是很高效的,比expando属性存取要快20倍以上。
上述判断,由DOM中的 document.expando 特性也可以佐证。当 document.expando=false 之后,你将不能使用 window.x = xxx 的方式新建全局变量,但是仍然可以用 x = xxx / var x = xxx 。
4. 在访问window.x时,如果已经有按照内建方式建立的x,则进行window.x到x的绑定,即产生一个指针指向内建方式创建的x,然后就凭借此指针来进行存取操作。然而在这里IE的开发者忘记了x引用可能被delete的情况,在x被delete之后,指针就失效了,从而导致之前的“Out of memory”错误。
5. 在对window.x进行赋值时,如果不存在按照内建方式保存的x,则会以window的expando属性方式保存(如果允许expando的话)。
6. 而在访问x时,如果没有按照内建方式建立的x引用,则检查引擎所连接的window对象上是否有x,即window上是否有expando。如果有,就建立x引用并指向window上的expando。如果没有,就扔出TypeError(按照标准其实应该扔出ReferenceError)。
7. 那么为什么在以expando方式建立变量后,存取window.x比存取x慢呢?
老实说,这个问题很难回答,只能大胆猜想一下:
存取window.x的步骤:
a. JScript引擎调用DOM对象存取属性的方法,假设记做 DOM::Window.get/setAttribute("x")
b. DOM::Window.get/setAttribute()方法先询问JScript引擎是否已经有内建全局变量x,假设记做 JScript::Global.hasProperty("x")
c. JScript::Global.hasProperty("x")返回false
d. 于是DOM::Window.get/setAttribute()方法存取expando属性,假设记做 DOM::Window.get/setExpando("x")
e. 将结果返回给JScript引擎
存取x的步骤:
a. JScript引擎查找是否存在x引用
b. JScript引擎根据x引用调用DOM::Window.get/setExpando("x")
c. DOM::Window.get/setExpando("x")返回结果给JScript引擎
根据上述猜想,存取window.x,是JScript调用DOM,DOM再回调JScript;而存取x,则只有JScript调用DOM。这就是性能差大概一倍的原因。
好了,绕了一大圈之后,我们来解释一下最初的代码为什么会有这样的结果。
<script> window.x = 1 </script> <script> var x alert(x) </script>
这段代码会先以expando方式创建x。而后var x声明所进行的初始化操作,并不依赖于DOM,所以不会检测是否存在expando。道理上说应该检测,但是由于罹患DID,恰好此处JScript引擎并没有检测expando,而只会检测内建存储。并不存在内建的x,所以x引用就被重新初始化了,而且这次是以内建方式建立的。
而合并在一起后
<script> window.x = 1 var x alert(x) </script>
var x声明会被提前,所以会以内建方式创建。执行 window.x = 1 时,已经有了内建的x,所以会建立到内建x的绑定,并对其赋值,而不会以expando方式保存。
先加上一句 x = xxx 的赋值语句
<script> x = null window.x = 1 </script> <script> var x alert(x) </script>
也会以内建方式创建x。这样之后的var x就不会重新初始化了。
最后说说治疗方案。
维基百科 写道
多重人格的根治需要好幾年的時間。
换到我们的语境下:
Dr. Hax 写道
IE的DID的根治可能还需要很多年时间(IE9?)。
当然,我们有些简单的应对之道。
1. 不用全局变量,不折腾window对象。
从编程上说,使用全局变量不是一个好习惯。从JS效率而言,全局变量效率比局部变量要低许多。再加上IE独有的DID症,咱能不用就不用吧!
2. 如果一定要用全局变量,坚持直来直去,不折腾window对象。
也就是只用 var x 的方式。效率最高,也避免了DID症的可能发作。
3. 宁可折腾DOM元素,也不折腾window对象。
动态变量名,即window[name]之类的,可用一个 var container={name:value} 来替代,或者最不济的情形,你存到一个DOM元素上也好!
一样expando,DOM元素相比window,有个重要优点是有clearAttributes()方法可以清空所有属性(相当于delete操作),或者更快捷的方法是用parent.innerHTML或node.outerHTML直接清空。
或许你认为清空expando不重要,大谬!不信,你写个脚本给DOM元素上加10万个expando属性,然后按一次刷新看看。
附:DID疑难案例
<script> x = ((window.x = 'expando'), 0) alert('x = ' + x) //window.x try { alert('delete x -> ' + (delete x)) } catch(e) { alert(e.name + ': ' + e.description) } try { alert('window.x = ' + window.x) } catch(e) { alert(e.name + ': ' + e.description) } try { alert('x = ' + x) } catch(e) { alert(e.name + ': ' + e.description) } </script> <script> alert('x = ' + x) var x = 'var' </script>
在IE下输出什么?恢复被注释掉的第三行代码后呢?
答案请自己动手试验。
PS. 钻研DID多年的Dr. Hax还透露,实际上IE全局变量的DID不仅有两个变量格,实际上还有第三个变量格!你猜到了吗?欢迎留言竞猜。
评论
20 楼
libmw
2011-11-04
libmw 写道
呼呼。。ie8治好了
刚试了下,悲剧得还没治好
19 楼
libmw
2011-11-04
呼呼。。ie8治好了
18 楼
bmcsy
2010-06-17
虽然只是现在才看到,頩已经看完了,在概叹——我的神呀之余,真让人收获不少~~也知道了平时不晓得的。
17 楼
felsenlee
2009-12-22
cuixiping 写道
分析的很全面和深入。
ie中的元素id可以直接当变量名一样使用,但是这个id变量不能被赋值.
<body id='body'>
<script type="text/javascript">
body=1;
</script>
</body>
这样就会脚本错误提示“对象不支持此属性或方法”。
所以,是定义变量,最好老老实实的var.上例中使用var body=1才可以。
ie中的元素id可以直接当变量名一样使用,但是这个id变量不能被赋值.
<body id='body'>
<script type="text/javascript">
body=1;
</script>
</body>
这样就会脚本错误提示“对象不支持此属性或方法”。
所以,是定义变量,最好老老实实的var.上例中使用var body=1才可以。
“ body=1;”是个什么操作呢?比较奇怪!这肯定会报错啊,赋值也不是直接给对象赋吧。
16 楼
cuixiping
2009-12-20
分析的很全面和深入。
我想,把window.x和var x混用本身就是个很坏的编程习惯,没有var就直接x=xxx也是很坏的编程习惯。
ie中的元素id可以直接当变量名一样使用,但是这个id变量不能被赋值.
<body id='body'>
<script type="text/javascript">
body=1;
</script>
</body>
这样就会脚本错误提示“对象不支持此属性或方法”。
所以,是定义变量,最好老老实实的var.上例中使用var body=1才可以。
我想,把window.x和var x混用本身就是个很坏的编程习惯,没有var就直接x=xxx也是很坏的编程习惯。
ie中的元素id可以直接当变量名一样使用,但是这个id变量不能被赋值.
<body id='body'>
<script type="text/javascript">
body=1;
</script>
</body>
这样就会脚本错误提示“对象不支持此属性或方法”。
所以,是定义变量,最好老老实实的var.上例中使用var body=1才可以。
15 楼
s79
2009-11-29
似乎这个问题也能在这找到解释(IE7以后直接提供了XMLHttpRequest)。
if(typeof XMLHttpRequest=="undefined"){
alert(0);
var XMLHttpRequest={}; //省略。
}
if(typeof XMLHttpRequest=="undefined"){
alert(0);
var XMLHttpRequest={}; //省略。
}
14 楼
cuckoosnest
2009-11-15
有没有发现用chrome运行那段性能力测试代码非常慢,5,6秒的级别,opera非常快六七十ms级别。 大概是什么原因?
13 楼
achun
2009-08-11
Dr.Hax
哈哈,太好玩了,这个可以找个声优做成有声版,小说?广播剧?
油菜呀
哈哈,太好玩了,这个可以找个声优做成有声版,小说?广播剧?
油菜呀
12 楼
Army
2009-03-26
貌似我一猜就猜中了,别人连机会都没有,没留啥悬念下来,可惜了。
11 楼
hax
2009-03-26
Army 写道
我还是选C,看看《ajax实战》吧~另外,签名是签Dr. hax呢,还是签真实姓名呢?我拿去炫耀一下去~
站内留言地址,我邮寄给你,呵呵。
10 楼
Army
2009-03-26
hax 写道
Army 写道
猜一下,难道是ie里对dom节点的id直接引用?中!发奖品了。。。奖品选项如下:A. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进午餐B. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进晚餐C. 获得由Dr. Hax签名的《Ajax实战:实例详解》一本D. 获得没有Dr. Hax签名的《Ajax实战:实例详解》一本
吃惊,我居然猜对了!
我住在上海南站附近,接近闵行区,张江的话太远了……
我还是选C,看看《ajax实战》吧~另外,签名是签Dr. hax呢,还是签真实姓名呢?我拿去炫耀一下去~
9 楼
hax
2009-03-26
Army 写道
猜一下,难道是ie里对dom节点的id直接引用?
中!
发奖品了。。。奖品选项如下:
A. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进午餐
B. 与Dr. Hax在张江地铁站周边方圆5公里以内的食堂里共进晚餐
C. 获得由Dr. Hax签名的《Ajax实战:实例详解》一本
D. 获得没有Dr. Hax签名的《Ajax实战:实例详解》一本
8 楼
Army
2009-03-25
猜一下,难道是ie里对dom节点的id直接引用?
7 楼
Army
2009-03-25
前阵子在开发JAte的时候就碰到了,如果var一个object和swf的名字相同,js取得这个swf对象的时候就会取到var的那个变量上,得改个名字才行。
原理原来在这里……
原理原来在这里……
6 楼
hax
2009-03-24
beijing.josh 写道
IE的分裂症还包括:window.clearInterval能重写,clearInterval不能重写.所有以内建方式建立的window方法的引用都不能重写和删除.是否这是第三个变量格?
不是的。要构成“变量格”必须满足Dr. Hax定义的条件:拥有各自操作模式和存储。
其中的关键是一个全局变量引用的目标到底是指向哪里。第三种变量格其实(在早期脚本里)很常见的。
5 楼
hax
2009-03-24
麦田的颜色 写道
sorry,Hax,好久没联系。
我不知道我问你要过MSN没?加我一下吧。我是小麦。
加过了,不过我99%时候不在线。。。
4 楼
beijing.josh
2009-03-23
IE的分裂症还包括:window.clearInterval能重写,clearInterval不能重写.
所有以内建方式建立的window方法的引用都不能重写和删除.
是否这是第三个变量格?
所有以内建方式建立的window方法的引用都不能重写和删除.
是否这是第三个变量格?
3 楼
麦田的颜色
2009-03-23
sorry,Hax,好久没联系。
我不知道我问你要过MSN没?加我一下吧。我是小麦。
我不知道我问你要过MSN没?加我一下吧。我是小麦。
2 楼
lifesinger
2009-03-16
赞,Dr. Hax 太有意思啦
开诊所吧
开诊所吧
1 楼
NOWGOO
2009-03-16
非常棒的文章!
发表评论
-
论ES6模块系统的静态解析
2013-03-14 04:56 15952本文是Dave Herman的《Stati ... -
如何创建一个JavaScript裸对象
2012-08-27 02:11 8120所谓裸对象,即 naked object ,是指没有原型(sp ... -
JavaScript语句后应该加分号么?
2012-06-19 03:10 14472这是一个老生常谈的问 ... -
shim是应该抛异常还是应该fail silently?
2011-08-11 17:26 5672玉伯发布了es5-safe模块 ... -
7月30日的广州演讲视频和Slides
2011-08-01 23:38 32007月30日在W3CTech广州站活动上的演讲,题目是:ECMA ... -
如何判断一个函数的意图是被用作构造器,也就是可视为“类”
2011-07-21 13:55 2975前提是不要求做什么特殊标记。只是最大可能的猜测函数的作用大概是 ... -
关于国内前端和JS技术发展的乱想
2011-07-19 18:53 33355玉伯在我的一条微博后面写了一些(和主题不是很相关但)非常值得思 ... -
Module与Trait的比较
2011-08-12 12:50 4056最近我多次提及module和trait。 粗看,我们可以发现 ... -
如何将let结构(block scope)转换到当前的JavaScript代码
2011-07-12 17:24 3034本文是对如何将let结构转换到ES3代码的补充。 首先,原文 ... -
JavaScript的未来方向之观察
2011-07-12 02:53 8385最近每次去杭州,都有 ... -
我为什么力挺NodeJS
2011-07-04 00:27 0之前在参加CNodeJS社区在 ... -
JS之父再谈JS历史(续完)
2010-12-31 04:20 3460又到年底,我觉得是时候还债了。自开blog来,我出了不少“太监 ... -
我为什么是DC黑续,兼答Tin
2010-04-27 14:29 0我同意安全是一个重要问题。我不同意的是把所谓安全放到凌驾于其他 ... -
我为什么是DC黑─Why I disagree with Douglas Crockford
2010-04-26 17:51 11050参加完了QCon北京大会, ... -
写对正则:一行代码,速度差50倍
2009-05-12 03:43 60232009-05-11 A lesson of ... -
JavaScript的EOS(分号)问题
2009-05-08 16:24 5793在http://bbs.51js.com/viewthre ... -
JavaScript五大关键字
2009-05-06 17:53 4778近期做语法高亮项目的副产品,是统计了一下几个主流JS工具包中各 ... -
curry和partial的差别
2009-03-28 00:15 372551js上asfman翻译了http://ejohn.org/ ... -
Eval is Evil , With evil too
2009-03-27 18:39 0with的问题: 2009-3-27 17:12:40 ... -
JScript下Array对象的性能问题
2009-02-14 02:51 4005今天看了微软JScript官方blog上去年的两篇文章: ht ...
相关推荐
4. 回避型人格障碍是指常被迫采用多种心理防御机制来应付压力。 5. 评价心理健康的统计学标准的理论基础为正态分布。 6. 专业技术人员可以通过完成心理测验的方式来评估自己的职业发展。 7. 职业生涯是贯穿于个人...
关于尿嘧啶的电子附着实验表明,通过解离式电子附着反应(Dissociative Electron Attachment, DEA)可以生成氢自由基[3]。这一过程是一种有效的方式,能够在远低于电离能的能量水平下分解碱基。 实验研究表明,在被...
这个项目旨在探索人类感知的边界,通过增强现实(Augmented Reality, AR)和虚拟现实(Virtual Reality, VR)技术,模拟出一种“主观解体”(Dissociative Experiences)的感觉,类似于类淋巴瘤的状态。 Oculus ...
内容概要:本文全面介绍了Scratch编程语言,包括其历史、发展、特点、主要组件以及如何进行基本和进阶编程操作。通过具体示例,展示了如何利用代码块制作动画、游戏和音乐艺术作品,并介绍了物理模拟、网络编程和扩展库等功能。 适合人群:编程初学者、教育工作者、青少年学生及对编程感兴趣的各年龄段用户。 使用场景及目标:①帮助初学者理解编程的基本概念和逻辑;②提高学生的创造力、逻辑思维能力和问题解决能力;③引导用户通过实践掌握Scratch的基本和高级功能,制作个性化作品。 其他说明:除了基础教学,文章还提供了丰富的学习资源和社区支持,帮助用户进一步提升技能。
mmexport1734874094130.jpg
基于simulink的悬架仿真模型,有主动悬架被动悬架天棚控制半主动悬架 [1]基于pid控制的四自由度主被动悬架仿真模型 [2]基于模糊控制的二自由度仿真模型,对比pid控制对比被动控制,的比较说明 [3]基于天棚控制的二自由度悬架仿真 以上模型,说明文档齐全,仿真效果明显
内容概要:本文档是《组合数学答案-网络流传版.pdf》的内容,主要包含了排列组合的基础知识以及一些经典的组合数学题目。这些题目涵盖了从排列数计算、二项式定理的应用到容斥原理的实际应用等方面。通过对这些题目的解析,帮助读者加深对组合数学概念和技巧的理解。 适用人群:适合初学者和有一定基础的学习者。 使用场景及目标:可以在学习组合数学课程时作为练习题参考,也可以在复习考试或准备竞赛时使用,目的是提高解决组合数学问题的能力。 其他说明:文档中的题目覆盖了组合数学的基本知识点,适合逐步深入学习。每个题目都有详细的解答步骤,有助于读者掌握解题思路和方法。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
操作系统实验 Ucore lab5
基于matlab开发的学生成绩管理系统GUI界面,可以实现学生成绩载入,显示,处理及查询。
老版本4.0固件,(.dav固件包),支持7700N-K4,7900N-K4等K51平台,升级后出现异常或变砖可使用此版本。请核对自己的机器信息,确认适用后在下载。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
YOLO算法-杂草检测项目数据集-3970张图像带标签-杂草.zip
E008 库洛米(3页).zip
内容概要:本文详细阐述了基于西门子PLC的晶圆研磨机自动控制系统的设计与实现。该系统结合了传感器技术、电机驱动技术和人机界面技术,实现了晶圆研磨过程的高精度和高效率控制。文中详细介绍了控制系统的硬件选型与设计、软件编程与功能实现,通过实验测试和实际应用案例验证了系统的稳定性和可靠性。 适合人群:具备一定的自动化控制和机械设计基础的工程师、研究人员以及从事半导体制造的技术人员。 使用场景及目标:本研究为半导体制造企业提供了一种有效的自动化解决方案,旨在提高晶圆研磨的质量和生产效率,降低劳动强度和生产成本。系统适用于不同规格晶圆的研磨作业,可以实现高精度、高效率、自动化的晶圆研磨过程。 阅读建议:阅读本文时,重点关注晶圆研磨工艺流程和技术要求,控制系统的硬件和软件设计方法,以及实验测试和结果分析。这将有助于读者理解和掌握该自动控制系统的实现原理和应用价值。
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
深圳建筑安装公司“挖掘机安全操作规程”
YOLO系列算法目标检测数据集,包含标签,可以直接训练模型和验证测试,数据集已经划分好,包含数据集配置文件data.yaml,适用yolov5,yolov8,yolov9,yolov7,yolov10,yolo11算法; 包含两种标签格:yolo格式(txt文件)和voc格式(xml文件),分别保存在两个文件夹中,文件名末尾是部分类别名称; yolo格式:<class> <x_center> <y_center> <width> <height>, 其中: <class> 是目标的类别索引(从0开始)。 <x_center> 和 <y_center> 是目标框中心点的x和y坐标,这些坐标是相对于图像宽度和高度的比例值,范围在0到1之间。 <width> 和 <height> 是目标框的宽度和高度,也是相对于图像宽度和高度的比例值; 【注】可以下拉页面,在资源详情处查看标签具体内容;
大题解题方法等4个文件.zip