每日读《你不知道的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
});

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

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

小结

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

明天也会继续挖宝藏哒!

相关推荐
三小河3 分钟前
overflow:auto 滚动的问题,以及flex 布局中如何设置
前端·javascript
薛定谔的算法7 分钟前
phoneGPT:构建专业领域的检索增强型智能问答系统
前端·数据库·后端
Hilaku8 分钟前
Token已过期,我是如何实现无感刷新Token的?
前端·javascript·面试
小文刀69612 分钟前
2025-35st-w-日常开发总结
前端
我是日安14 分钟前
从零到一打造 Vue3 响应式系统 Day 8 - Effect:深入剖析嵌套 effect
前端·vue.js
Mor_18 分钟前
UE5核心宏标记 (UCLASS, UPROPERTY, UFUNCTION) 学习笔记
面试
小lan猫18 分钟前
React学习笔记(一)
前端·react.js
晨米酱18 分钟前
JavaScript 中"对象即函数"设计模式
前端·设计模式
拜无忧19 分钟前
【教程】Nuxt v4 入门指南与实践 (vue前端角度开发)
前端·nuxt.js
云枫晖22 分钟前
手写Promise-什么是Promise
前端·javascript