YAHOO 的三种写法
// 写法1:
var YAHOO = YAHOO || {};
// 写法2:
var YAHOO = window.YAHOO || {};
// 写法3:
if(typeof YAHOO === "undefined" || !YAHOO) {
var YAHOO = {};
}
上面三种写法有什么区别?
写法1和写法2,都在全局作用域时,结果上并无区别。但如果在闭包里,写法1将不是预期结果:
var YAHOO = {};
// ...
(function(){
var YAHOO = YAHOO || {};
YAHOO.util = {};
})();
// ...
alert(YAHOO.util); // => undefined
原因很简单,闭包里,YAHOO 是局部变量。
写法2和写法3,在 99.99% 的应用场景下,结果上是等价的。但写法3更严谨,因为 JavaScript 的运行环境不一定是浏览器,因此全局变量并一定在挂载在 window 对象上。
写法3虽严谨,但也并非总是预期:
<script type="text/javascript">
var YAHOO = 2;
</script>
<script type="text/javascript">
if(typeof YAHOO === "undefined" || !YAHOO) {
var YAHOO = {};
}
YAHOO.util = {};
alert(YAHOO.util); // => undefined
</script>
上面一直提到一个概念:预期。我觉得这个预期可以描述为:
如果 YAHOO 已经定义成一个普通对象 {} 或函数对象 function, 则不要覆盖原来的定义。否则重新定义。
在这个预期的定义上,更严谨的一种写法是:
// 写法4:
if((typeof YAHOO !== "object" || window.YAHOO === null)
&& typeof YAHOO !== "function") {
var YAHOO = {};
}
2009-09-02 更新:上面的写法增加 null 判断。
注:绝大部分情况下,写法2已经足够用。

September 1st, 2009 on 9:00
写法4也是不严谨的,如:
先定义 var YAHOO = null;
其实框架上的根命名空间是没人会改的,如果你改了出了问题只能怪你自己了(你就慢慢找原因吧)。
所以我觉得第一种足够了。
September 1st, 2009 on 9:31
代码还是越健壮越好!
September 1st, 2009 on 10:01
1楼有道理,感谢指正。文中写法4已更新。
我觉得最好的写法还是 var YAHOO = window.YAHOO || {};
September 1st, 2009 on 14:50
我想请教一个问题:下面的alert(YAHOO.util);为何得到的是undefined而不是报一个错误,YAHOO=2那么YAHOO.util难道不是2.util吗?alert(2.util);是会报错的,而alert(YAHOO.util);为何不会错?可否解释一下,谢谢!
var YAHOO = 2;
if(typeof YAHOO === “undefined” || !YAHOO) {
var YAHOO = {};
}
YAHOO.util = {};
alert(YAHOO.util); // => undefined
September 1st, 2009 on 20:06
@john: alert(2.util) 中,小数点不是下标运算符,而是小数点的点。上面的 YAHOO.util 等价 2..util, 中间两个点。
September 1st, 2009 on 21:35
john 想问为什么 YAHOO.util 是 undefined 吧
var YAHOO=2;
执行 YAHOO.util={}; 时生成临时数字对象,util作为他的属性,完了临时对象也没了,
下次 alert(YAHOO.util) 是另外一个临时对象,
和 java 的 autobox 有点像
September 1st, 2009 on 22:00
什么写法都不是万能的,都是要依赖于其存在的上下文,在闭包如此频繁的js中更是如此。
September 1st, 2009 on 22:09
(function(){
var YAHOO = YAHOO || {};
YAHOO.util = {};
})();
这是匿名函数,不是闭包吧…
September 2nd, 2009 on 8:27
@john & yiminghe: yiminghe 的解释很到位,和 Java 的 autobox 类似。我解释的是为何 alert(2.util) 会报错。
@天堂:匿名函数的运行环境,就是一个闭包。
September 2nd, 2009 on 9:43
噢,明白,嘿嘿
September 2nd, 2009 on 10:37
@lifesinger & yiminghe:
非常感谢两位朋友的解释,我之前也认为应该是autobox,所以觉得2.util理所当然应该被autobox,只是后来发现alert(2.util) 会报错。基于alert(2.util)得到的结果,我对alert(YAHOO.util)得到undefined觉得困惑。
不怕你们笑话,到现在还对alert(2.util)会报错,而alert(2..util)可以得到正确结果不是太明白,这个”2″怎么就成了”2.”,可否对此作进一步解释,谢谢!
September 2nd, 2009 on 10:58
@john: 2.util 等价 (2.)util 语法错误。 2..util 等价 (2.).util
不知道这样说明白了没? 在数字后面,小数点会优先解释成为小数点的点,而不是C++里的 ->
September 2nd, 2009 on 11:10
@lifesinger
呵呵,非常感谢朋友的耐心解答,这下清楚了
November 27th, 2009 on 10:46
何必那么麻烦,最美丽的写法,性能最好,代码最简洁的写法如下:
window.YAHOO ||(window['YAHOO ']={});
November 27th, 2009 on 13:56
@icerain: 上面的写法一点也不美丽哦
leave a reply