目录
变量的分类:local variables 和 global varibles
在学习函数内定义的变量(local variables局部变量)时,看到有提示:推荐尽可能使用 local variables,不要使用 global variables 全局变量,因为这样可以让代码干净且易于理解 。
见链接:Functions (javascript.info)
突然想到,这不就是之前看到过的“避免污染全局变量”么,突然一下子茅塞顿开。把之前的项目代码翻来看,突然就理解了之前头疼不已的自调用函数问题。
下面记录一下:
变量的分类:local variables 和 global varibles
只有函数内部 和 语句 statements 的{}符号内 的代码属于 block 块级作用域,在这里面声明的变量叫做 local variables 局部变量;除此之外地方声明的变量叫做 global varibles 全局变量。
访问规则是:
- 局部变量只能在 block 内访问,不能在全局访问。比如说函数内部声明的变量 a, 在这个函数外就访问不到(对于访问不到的属性名或变量,JavaScript 会返回 undefined 表示 unassigend 未赋值)。
- 但是对于全局变量,可以在任意位置访问,也就是说,在 block 中也能访问(这里解释一下:全局变量是 window 对象的某个属性名。比如全局变量 b,就可以通过 window.b 在任意位置访问到)。
因此,可以通过下面第 118 行代码来暴露函数内部的对象 Game,供函数外部调用,让 Game 变为 一个全局变量。
具体做法是:
原理:
对于一个对象 obj 来说,如果 obj 内部没有属性名 key, 就可以通过赋值的方式添加属性名,即 obj.key = 'something' 。
因此,在这里通过 window.Game = Game,直接给 window 增加了Game这个属性名,让 Game 成为了全局变量,在函数外部也可以被调用。这样就突破了 block 块级作用域 对局部变量 Game的限制。
匿名函数
定义函数一般有两种方式:
参考链接:JavaScript匿名函数的理解_w3cschool
第一种:function 关键字
// function 关键字定义
function foo(x) {
return x * 2
}
第二种:匿名函数
// 匿名函数定义
// 方式一:赋值给变量
let foo = function (x) {
return x * 2
}
// 方式二:自调用函数创建
(function (x) {
return x * 2
})(5);
匿名函数的调用
匿名函数,即没有函数名的函数,因此不能直接被外部调用,只能通过 赋值 或者 自执行函数 调用。
参考链接:(4条消息) JS 匿名函数——几种不同的调用方式_足各路-优快云博客_js 匿名函数
自调用函数IIFE
作用
在定义函数的时候就执行函数,因此又叫自执行函数。
它可以封闭作用域,在作用域外无法调用其内部的函数,避免作用域内定义的变量污染全局变量 。比如上图中,就无法在自调用函数外访问 runSnake 等函数(但是由于通过 window.Game = Game 把函数内部的 Game 对象暴露给了外部,因此在外部可以通过 window.Game 访问到局部变量 Game,这样就限定了访问局部变量的方式)。
实现原理
通过操作符等各种符号,将匿名函数转换为函数表达式,并添加 () 调用。
常见形式
是 (匿名函数)(); ,比如 (function () {})(); 或者 (function foo() {})();
除了用 () 包裹匿名函数,自执行函数还可以有多种形式:可以在匿名函数前加上操作符。因为操作符可以把 function 关键字转换成函数表达式。比如 +function () {}();
参考链接:浅谈自执行函数(立即调用的函数表达式) - 简书 (jianshu.com)
句尾要不要加分号
JavaScript中可以不写分号,但是多个自调用函数之间,必须加上分号(要么在之前,要么在之后)。否则代码压缩后,上一个函数和自调用函数合并在一起,容易报错。
参数:可不传
(function () {parameter1, parameter2})(argument1, argument2);
parameter 形参
argument 实参
上图中的参数传了 window 和 undefined,原因是:
传入 window 全局对象,作用:
- 把 window 中的变量(即全局变量)变成函数内的 局部变量。可以让内部函数执行时,不需要将作用链退到顶层作用域(即全局作用域)去寻找 window,这样可以提高效率;
- 将来压缩代码时,可以把 function(window) 压缩为 function(w),减少代码量。
传入 undefined 作用:在有的老版本的浏览器中undefined可以被重新赋值,这里可以防止undefined被重新赋值。