1. 什么是自执行的匿名函数?
它是指形如这样的函数: (function {// code})();
2. 疑问
为什么(function {// code})();可以被执行, 而function {// code}();却会报错?
3. 分析
(1). 首先, 要清楚两者的区别:
(function {// code})是表达式, function {// code}是函数声明.
(2). 其次, js"预编译"的特点:
js在"预编译"阶段, 会解释函数声明, 但却会忽略表式.
(3). 当js执行到function() {//code}();时, 由于function() {//code}在"预编译"阶段已经被解释过, js会跳过function(){//code}, 试图去执行();, 故会报错;
当js执行到(function {// code})();时, 由于(function {// code})是表达式, js会去对它求解得到返回值, 由于返回值是一 个函数, 故而遇到();时, 便会被执行.
另外, 函数转换为表达式的方法并不一定要靠分组操作符(),我们还可以用void操作符,~操作符,!操作符……
如:
!function(){ alert("另类的匿名函数自执行"); }();
佚名函数()() | (()) |
(function() { alert('hello') } )(); (function(v) { alert(v) } )('hello'); |
(function() { alert('hello') } ()); (function(v) { alert(v) } ('hello')); |
有名函数()() | (()) |
(function fn() { alert('hello') } )(); |
(function fn() { alert('hello') } ()); |
对象函数()() | 对象函数(()) |
({ init:function(){ alert('hello') } }).init(); |
({ init:function(){ alert('hello') } }.init()); |
对象内部() | 不可这样调用 |
var foo = { fn: function (x) { return x % 2 != 0 ? 'yes' : 'no'; }(1) }; alert(foo.fn); // 'yes' |
var foo = { fn: function (x) { return x % 2 != 0 ? 'yes' : 'no'; }(1) }; alert(foo.fn()); |
对象+","+函数+() | “对象”可以为如下,自己可试 |
1, function () { alert('anonymous function is called'); }(); |
1、任意数字 2、特殊字符(!、~、- 、+) 3、void 4、true、false 当然这些也可以组合使用。 |
()应用,设计模式之单例模式 | 自定义对象 |
//()应用 var Singleton = (function () { function init() { /*这里定义单例代码*/ return { publicMethod: function () { alert('hello world'); } }; } return { getInstance: function () { return init(); } }; })(); /*调用公有的方法来获取实例:*/ Singleton.getInstance().publicMethod(); |
var obj = {}; (function (q) { q.publish = function (str) { alert(str); } } (obj)); //提交obj全局对象 obj.publish('hello');//hello (function (a) { a.publish = function (str) { alert(str); } } (window)); //window对象 publish('hello'); |
著名应用实例:jQuery | 设计模式之迭代器模式 |
(function() { var jQuery = (function() { //构建jQuery对象 var jQuery = function() { //实例init() return new jQuery.fn.init(); }; jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function() { var match; }, jQuery: "1.7.1" }; // 合并 init()的属性为jQuery.fn jQuery.fn.init.prototype = jQuery.fn; //返回jQuery return jQuery })(); //定义jQuery全局对象 window.jQuery = window.$ = jQuery; })(window); //应用实例 alert($().jQuery);//1.7.1 |
var fn = (function () { var index = 0, data = [1, 2, 3, 4, 5], length = data.length; return { length: length, rewind: function () { index = 0; }, current: function () { return data[index]; } }; } ()); alert(fn.current()); |
根据参数选择执行对象 | |
var fn=(function(){ var obj={ i1:function(){ return 'a'; }(), i2:function(){ return 'b'; }() }; //json格式,可以无序排列 var json={"1":"i1","2":"i2"}; //array数组,有序排列 // var ar=["i11","i12"]; return { init:function(i){ return obj[json[i]]; } }; })(); alert(fn.init(1)); |
return { ini: function(X) { //声明一个函数,名称为ini X.__MSG_QS__ = {}; //为传进来的对象添加属性 X.on = C; //为传进来的对象添加方法 X.dm = G; //为传进来的对象添加方法 return X } }
|
使用闭包: (function($) {
// Code goes here })(jQuery); 这是来自jQuery官方的插件开发规范要求,使用这种编写方式有什么好处呢? a) 避免全局依赖。 b) 避免第三方破坏。 c) 兼容jQuery操作符'$'和'jQuery ' 我们知道这段代码在被解析时会形同如下代码: var jq = function($) {
// Code goes here }; jq(jQuery); |
利用匿名函数绑定事件 var obj = document.getElementById("psd"); obj.onclick=(function(){ return function(){alert('i');} })()
|
1.佚名函数 function() { // } 2.分组正则调用佚名函数 (function() { // })(); 3.定时调用佚名函数 setTimeout(function(){alert('msg')); 4.佚名函数返回对象 var bird = (function() { return { type: pro, attack: func }; }()); 5.给佚名函数传弟参数,等价4 (function( bird ) { bird.type = "red"; bird.attack = function() { }; }( window.bird = window.bird || {} )); |