作者mrbigmouth (拒绝崩溃的蒲公英)
看板Ajax
标题Re: [问题] (...)()或(...)(window)是什麽意思?
时间Sat Jul 14 00:56:33 2012
※ 引述《cyutdt (DT)》之铭言:
: 常在程式看到
: (function() {
: ...
: })();
: 或
: (function() {
: ...
: })(window);
: 我已经看过closure的相关教学和讨论
: 还是不晓得这跟closure是否有关联
: 还是跟$(document).ready(function(){});有什麽关系呢?
: 看到一些这种范例
: 不晓得为什麽要这样写
虽然我觉得google一定找得到答案
但现在刚好无聊就来说一说我的理解好了
如有错误烦请指证
(function() {})()
上面这种格式
就是所谓的self invoking anonymous function
自我 执行 匿名 函数
在程式逻辑上是"制造一个匿名的函数并且立刻执行"
其目的主要在於产生一个私有的scope,使在其内宣告的变数不会与外界混淆
以我最常使用的格式为例,会在写一些独立运行的网页程式的一开始写出如下的宣告
(function(window) {
var document = window.document,
$ = window.jQuery,
variableA,
variableB,
variableC,
.
.
.
variableN;
//下面才开始写程式
//写到这里结束程式
//如果有必要,将需要输出的函式/功能指派到window下的广域变数
window.OOXX = variable???;
})(window);
这样做最主要的好处在於,
在这个里面所宣告的变数绝对不会被外界的变数干扰(因为指不到),
不管该网页引入了多少library、後来者又乱插入了多少script、
server或使用者浏览器乱安装的plugin在网页後方又加了什麽奇怪的坏掉script....
我写在这个scope里的区域变数都绝对不可能会被影响到,
也因此保证了我写出的这个独立运作的程式在自己运作时绝对不会有问题。
同时,一些用过即丢的变数也不会一直挂在广域环境下占记忆体,
因为全部的变数都是区域变数,使用google closure compiler等软体进行minify化
时也能省掉更多的空间
至於在後方的括号里丢入window,
是为了增加读取的速度。
这里的相关关键字叫做Scope Chain。
当你使用一个变数时,若javascript在当前环境找不到该名称的变数,
就会继续往外找寻,一直找到最外层的全域物件上还找不到时,才会报错
而大家都知道,目前所有浏览器的全域物件都叫window。
所有你宣告的广域函式跟变数都会挂在window下,
如果你想在上面的self invoking function里使用任何广域变数,
javascript就得多经过一次的「找不到的过程」才能找到。
但是只要你把window当成参数丢进你的self invoking function里面,
window就会变成你自制scope里的区域变数,
於是就省下了一层查找的功夫。
虽然我也很怀疑到底等省下多少功夫啦
但多丢参数毕竟只是动几下手指的事而已。
而一些其他的变种
(function (window, undefined){
})(window)
在scope里宣告了undefined这个变数,
但是在自我执行时又不丢给他,
如此便能够完全确定你在使用undefined时代表的真的是undefined,
(是的,undefined是可以改变值的)
而这种
(function ($){
})(jQuery)
跟传window进去的意义是一样的
会这样使用的人应该是认为他在这个scope里面使用到的广域变数只有jQuery一个,
所以只丢jQuery进去,省去了在scope里面再次宣告的功夫。
另外,jQuery的$缩写是有可能改变的,
(通常在你同时使用其他以$为缩写的library时)
因此这种方法也兼顾了相容性。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 1.164.71.67
1F:推 tonest:感谢大大的说明~(好凑巧~遇到一样问题的人!!) 07/14 09:27