每日读《你不知道的JavaScript(上)》| 优化函数作用域用法

潜在问题

上一章我们提到函数作用域的用法。

js 复制代码
var a = 2;
function foo() {
    var a = 3;
    console.log(a); // 3
}
console.log(a); // 2

我们假若把 foo 中的内容隐藏起来,如下:

js 复制代码
var a = 2;
function foo() { ... }
console.log(a); // 2

发现在全局作用域中,多了一个 foo。

也就是说,我们本意是想隐藏 foo 中的内容,但却无意在全局作用域中新增一个具名函数。

如果函数不需要函数名(或者至少函数名可以不污染所在作用域),并且能够自动运行,这将会更加理想。

立即执行函数

js 复制代码
var a = 2; 
(function foo() { 
    var a = 3; 
    console.log( a ); // 3 
})(); 
console.log( a ); // 2

在给原先的 foo 函数外层加上两个括号之后,可见 foo 函数被包含在了一对()内部,此时function foo成为了一个 表达式 ,末尾的()代表 立即执行

这就是IIFE,立即执行函数表达式。

remind:它是一个表达式啊。


这里我补充一下关于函数表达式和函数声明的区别啊。

先看个 case。

js 复制代码
// 1
var foo = function(){ 
    console.log(1);
}();

// 2
function(){
    console.log(2);
}();

// 3
function foo(){
    console.log(3);
}();

执行结果如下:

后两个报错的原因是,不能在定义函数后马上调用。

第一个 case 不是函数声明,而是函数表达式。

js 复制代码
// 函数声明
function fn() {}; 

// 函数表达式 
var fn = function (){};

IIFE的进阶用法

定义函数并传参

js 复制代码
var a = 2;
(function fn(global){ // 入参命名为 global
    // ...
    console.log(global.a); // 2 --- 这里的 global 就是传入的 window
})(window);

在代码风格上,对 window 对象的引用比默认打印全局变量更加清晰。

虽然这么看着其实直接打印window.a也不是不行啊...

改变代码执行顺序

这种作用风格在 UMD 中比较常用。看看就行。

就拿书里面的来举例子吧:

js 复制代码
var a = 2;
(function IIFE(def) {
    def(window); // 把 window 对象传给 def
})(function def(global){ // 在第二个括号里定义函数 def
    var a = 3;
    console.log(a);
    console.log(global.a); // 2
});

看着真的很绕啊,虽然我也是真的不理解这样写有什么意义...

以后有机会遇见了这样的写法回来更文吧(汗流浃背了😥)

小结

今天收获最有含金量的小点就是区分函数声明和函数表达式。

明天也会继续挖宝藏哒!

相关推荐
Cacciatore->1 小时前
Electron 快速上手
javascript·arcgis·electron
vvilkim1 小时前
Electron 进程间通信(IPC)深度优化指南
前端·javascript·electron
某公司摸鱼前端2 小时前
ES13(ES2022)新特性整理
javascript·ecmascript·es13
心平愈三千疾2 小时前
通俗理解JVM细节-面试篇
java·jvm·数据库·面试
ai小鬼头3 小时前
百度秒搭发布:无代码编程如何让普通人轻松打造AI应用?
前端·后端·github
漂流瓶jz3 小时前
清除浮动/避开margin折叠:前端CSS中BFC的特点与限制
前端·css·面试
前端 贾公子3 小时前
在移动端使用 Tailwind CSS (uniapp)
前端·uni-app
散步去海边3 小时前
Cursor 进阶使用教程
前端·ai编程·cursor
清幽竹客3 小时前
vue-30(理解 Nuxt.js 目录结构)
前端·javascript·vue.js
weiweiweb8883 小时前
cesium加载Draco几何压缩数据
前端·javascript·vue.js