!function(){}.call()

一开始有个全局变量:

var a=1;
复制代码

现在不想让它受外界影响,即把a变成局部变量:

function fn1(){var a=1;}
复制代码

a成为局部变量了,但封装它的fn1是一个全局函数,a不会被覆盖,但fn1有可能被覆盖,所以a仍然是不安全的。 使用匿名函数封装:

但这样会被JS引擎解析为是要定义一个匿名函数,直接这样写语法上是错误的,会报错 前面加个!(取反),JS引擎判就不认为是在定义一个函数了,而是要执行后面的函数
但这样函数内部的代码并没有执行,看下面的证明:
要加call,调用这个函数:
1即是匿名函数内部代码得以执行后打印出来的,下一行undefined因为a是局部变量,在全局中打印是取不到a的值的。function(){}是匿名函数,函数即对象,对象的布尔值始终为true

函数是要有返回值的,不定义return的话默认返回undefined,undefined对应的布尔值为false

第一行语法报错,这也是为什么加!号的原因(执行匿名函数,而不是定义),下面是加不加return的区别。
总结:使用 !function(){}.call()这种格式可以来封装代码,!function(){}.call()本身是有返回值的(ture或false),但一般不会造成影响,我们最终想要的结果,就是这个匿名函数内部的代码得以执行,同时做到了:1.没有生成新的全局函数,避免被覆盖的可能2把代码放到匿名函数内部形成的局部作用域里,不受全局影响。
a现在成功的成为了一个安全的局部变量,但要如何在其他作用域下引用它呢?闭包

在匿名函数内部,定义一个具名函数,这个具名函数就可以在匿名函数的作用域下寻参,从而获取a的值(作用域链),然后把这个函数定义到window对象上(也可以让这个匿名函数return该具名函数),这样这个具名函数就成了全局函数,在任何作用域下都可以调用。然后让这个具名函数返回a,这样以来通过调用这个具名函数,就可以随时随地获得局部变量a的值。这种操作,就是闭包,闭包最大的特点,就是它可以“记住”诞生的环境,将函数内部和函数外部连接起来。总之就是每次调用一个函数,这个函数都只会在定义它的那个环境里去开始寻参,而不是在调用,使用它的环境下开始寻参。两次提到了‘开始’,是为了提醒被调用函数依照作用域链寻参的过程,不仅仅局限于定义它或调用它时的环境,如果找不到,会继续去更外层的作用域去找,下面是简单验证: 全局中调用:
局部作用域中调用:

无论外界怎么调用,a的值都不受影响。
闭包和立即执行函数的关系:立即执行函数先产生局部作用域和局部变量,然后利用闭包:即在这个局部作用域内部定义一个函数,使这个函数得以访问定义它的这个局部作用域中的变量,并以某种形式输出,实现闭包的意义。可以说,立即执行函数是闭包的前提。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值