详解JavaScript的闭包、IIFE、apply、函数与对象(5)

第3种写法为什么这样就能立即执行并且不报错呢?因为在javascript里,括号内部不能包含语句,当解析器对代码进行解释的时候,先碰到了(),然后碰到function关键字就会自动将()里面的代码识别为函数表达式而不是函数声明。

如果需要将函数表达式或匿名对象立即执行,可以使用如下方法:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IIFE</title> </head> <body> <script type="text/javascript"> //调用匿名函数 (function() { console.log("这是一个函数表达式"); })(); //调用匿名对象 ({ name: "foo", show: function() { console.log(this.name); } }).show(); console.log({ a: 1 }.a); console.log({ a: function() {} }.a()); </script> </body> </html>

运行结果:

详解JavaScript的闭包、IIFE、apply、函数与对象

3.5.4、各种IIFE的写法

//最常用的两种写法 (function(){ /* code */ }()); // 老师推荐写法 (function(){ /* code */ })(); // 当然这种也可以 // 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义 // 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式 // 但是两者交换则会报错 var i = function(){ return 10; }(); true && function(){ /* code */ }(); 0, function(){ /* code */ }(); // 如果你不怕代码晦涩难读,也可以选择一元运算符 !function(){ /* code */ }(); ~function(){ /* code */ }(); -function(){ /* code */ }(); +function(){ /* code */ }(); // 你也可以这样 new function(){ /* code */ } new function(){ /* code */ }() // 带参

如果是函数表达式,可直接在其后加"()"立即执行。

如果是函数声明,可以通过"()"、"+"、"-"、"void"、"new"等运算符将其转换为函数表达式,然后再加"()"立即执行。

详解JavaScript的闭包、IIFE、apply、函数与对象

3.5.5、参数

函数表达式也是函数的一种表达形式,同样可以像函数一样使用参数,如下所示:

(function (n){ console.log(n); })(100);

输出:100

其实通过IIFE还能形成一个类似的块级作用域,当块内的程序在使用外部对象时将优先查找块内的对象,再查找块外的对象,依次向上。

(function(win,undfd){ win.console.log("Hello"==undfd); })(window,undefined);

3.5.6、添加分号

为了避免与其它的javascript代码产生影响后报错,常常会在IIFE前增加一个分号,表示前面所有的语句都结束了,开始新的一语句。

var k=100 (function (n){ console.log(n); })(k);

上面的脚本会报错,因为javascript解释器会认为100是函数名。

var k=100 ;(function (n){ console.log(n); })(k);

这样就正确了,在javascript中一行语句的结束可以使用分号,也可以不使用分号,因为一般的自定义插件会使用IIFE,这是一段独立的代码,在应用过程中不能保证用户会加上分号,所以建议在IIFE前加上分号。

3.5.7、IIFE的作用

1)、提高性能

减少作用域查找时间。使用IIFE的一个微小的性能优势是通过匿名函数的参数传递常用全局对象window、document、jQuery,在作用域内引用这些全局对象。JavaScript解释器首先在作用域内查找属性,然后一直沿着链向上查找,直到全局范围。将全局对象放在IIFE作用域内提升js解释器的查找速度和性能。

function(window, document, $) {
}(window, document, window.jQuery);

2)、压缩空间

通过参数传递全局对象,压缩时可以将这些全局对象匿名为一个更加精简的变量名

function(w, d, $) { }(window, document, window.jQuery);

3)、避免冲突

匿名函数内部可以形成一个块级的私有作用域。

4)、依赖加载

可以灵活的加载第三方插件,当然使用模块化加载更好(AMD,CMD),示例如下。

A.html与B.html文件同时引用公用的common.js文件,但是只有A.html需要使用到StuObj对象,B.html不需要,但使用其它方法。

Student.js

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwfywf.html