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

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

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

小结

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

明天也会继续挖宝藏哒!

相关推荐
四喜花露水17 分钟前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy26 分钟前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
李老头探索35 分钟前
Java面试之Java中实现多线程有几种方法
java·开发语言·面试
web Rookie1 小时前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust1 小时前
css:基础
前端·css
帅帅哥的兜兜1 小时前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3
工业甲酰苯胺1 小时前
C# 单例模式的多种实现
javascript·单例模式·c#
yi碗汤园1 小时前
【一文了解】C#基础-集合
开发语言·前端·unity·c#
就是个名称1 小时前
购物车-多元素组合动画css
前端·css
编程一生2 小时前
回调数据丢了?
运维·服务器·前端