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

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

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

小结

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

明天也会继续挖宝藏哒!

相关推荐
啪叽1 分钟前
JavaScript可选链操作符(?.)的实用指南
前端·javascript
Ian在掘金2 分钟前
bat+python实现easy connect自动连接
前端·python
代码搬运媛4 分钟前
【react实战】如何实现监听窗口大小变化
前端·javascript·react.js
小桥风满袖6 分钟前
Three.js-硬要自学系列30之专项学习环境光
前端·css·three.js
Luckyfif9 分钟前
🤯由 性能指标 散发开来的 Performance API 被问爆了呀
前端·面试·性能优化
咸虾米12 分钟前
在uniCloud云对象内使用unipay的微信退款出现错误“uniPayCo.refund Error: token校验未通过”的解决方案
前端·后端
前端Hardy19 分钟前
HTML&CSS:产品卡片动画效果
前端·javascript
货拉拉技术24 分钟前
货拉拉开源:鸿蒙路由 TheRouter
android·前端·harmonyos
中杯可乐多加冰26 分钟前
工业4.0数字孪生新引擎:星图云开发者平台全景评测
前端·低代码·掘金·金石计划