我遇到了一些javascript或jQuery函数,它们在方法的末尾有一个封闭的值或对象。例如:
(function ($) {
var delay = 0;
$.fn.translate3d = function (translations, speed, easing, complete) {
var opt = $.speed(speed, easing, complete);
opt.easing = opt.easing || 'ease';
translations = $.extend({ x: 0, y: 0, z: 0 }, translations);
return this.each(function () {
var $this = $(this);
$this.css({
transitionDuration: opt.duration + 'ms',
transitionTimingFunction: opt.easing,
transform: 'translate3d(' + translations.x + 'px, ' + translations.y + 'px, ' + translations.z + 'px)'
});
setTimeout(function () {
$this.css({
transitionDuration: '0s',
transitionTimingFunction: 'ease'
});
opt.complete();
}, opt.duration + (delay || 0));
});
};
})(jQuery);
或
<script type="text/javascript">
(function (d, t) {
<snip>
})(document, 'script');
</script>
在函数结尾处括号括起来的项目的目的是什么?我在这里找到了几个答案,但没有任何解决方法。感谢
答案 0 :(得分:3)
它使用参数定义一个匿名函数,将值分配给函数的参数,然后调用它。
此方法的优点是,您不会使用除函数内的任何其他地方不会使用的函数和变量来污染您的命名空间。
更详细一点,
(function() {} ...
声明匿名函数并在结束时添加()
调用刚创建的函数。
答案 1 :(得分:2)
它形成一个自我调用的匿名函数。优点是所有标识符都限定在该函数内,而不是具有全局范围。
这是一个很好的链接,可以进一步详细说明:http://markdalgleish.com/2011/03/self-executing-anonymous-functions/
以下是一个例子:
(function() {
var foo = "bar";
console.log(foo); // prints bar
})();
console.log(foo); // prints undefined since foo is scoped within the function
在重写时,可能更容易理解上面的代码片段:
function fun() {
var foo = "bar";
console.log(foo);
}
fun();
两个代码段实现了同样的功能。唯一的区别是,在第一个片段中,您没有命名您的函数然后调用它。您可以将其创建为匿名函数,并立即调用它。
当您想要将对象绑定到某个变量时,这也很有用,例如在代码片段中使用jQuery
完成:
var $ = {}; // define $ to an empty object instead of the jQuery object
(function($) {
// within this function, $ will always be the jQuery object
// protecting you from re-definitions outside the funciton
console.log($);
})(jQuery);
上面的代码片段创建了一个匿名函数,它接受一个参数$
,然后立即调用传入jQuery
对象的函数,确保函数$
内的函数始终引用jQuery
对象。
自动调用匿名函数的另一个有趣的应用是当你想要在延迟执行的情况下将变量绑定到特定对象时。
var markers = []; //an array of google map markers
for(var i = 0; i < markers.length; i++) {
// do something with markers[i];
// then schedule it for removal after 2 seconds
setTimeout(function() { markers[i].setMap(null); }, 2000);
}
上面代码片段的问题在于,当标记删除代码在2秒后运行时,i
的值将会随时更改,因为循环将继续进行。这可以通过使用自调用anon函数创建闭包来解决:
for(var i = 0; i < markers.length; i++) {
// do something with markers[i];
// then schedule it for removal after 2 seconds
(function(j) {
setTimeout(function() { markers[j].setMap(null); }, 2000);
})(i);
}
现在,j
绑定到i
的当前值,因此当删除代码在2秒后运行时,它会在i
的预期值上运行,即使{ {1}}后来发生了变化。