从函数内变量的访问,到匿名函数和自调用函数

目录

变量的分类:local variables 和 global varibles

访问规则是:

具体做法是:

原理:

匿名函数

定义函数一般有两种方式:

匿名函数的调用

 自调用函数IIFE

作用

实现原理

常见形式

句尾要不要加分号

参数:可不传


在学习函数内定义的变量(local variables局部变量)时,看到有提示:推荐尽可能使用 local variables,不要使用 global variables 全局变量,因为这样可以让代码干净且易于理解 。

见链接:Functions (javascript.info)

 突然想到,这不就是之前看到过的“避免污染全局变量”么,突然一下子茅塞顿开。把之前的项目代码翻来看,突然就理解了之前头疼不已的自调用函数问题。

下面记录一下:

变量的分类:local variables 和 global varibles

只有函数内部语句 statements 的{}符号内 的代码属于 block 块级作用域,在这里面声明的变量叫做 local variables 局部变量;除此之外地方声明的变量叫做 global varibles 全局变量。

访问规则是:

  1. 局部变量只能在 block 内访问,不能在全局访问。比如说函数内部声明的变量 a, 在这个函数外就访问不到(对于访问不到的属性名或变量,JavaScript 会返回 undefined 表示 unassigend 未赋值)。
  2. 但是对于全局变量,可以在任意位置访问,也就是说,在 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 匿名函数——几种不同的调用方式_足各路-CSDN博客_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 全局对象,作用:

  1. 把 window 中的变量(即全局变量)变成函数内的 局部变量。可以让内部函数执行时,不需要将作用链退到顶层作用域(即全局作用域)去寻找 window,这样可以提高效率;
  2. 将来压缩代码时,可以把 function(window) 压缩为 function(w),减少代码量。

传入 undefined 作用:在有的老版本的浏览器中undefined可以被重新赋值,这里可以防止undefined被重新赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值