刚学JavaScript的时候,一直对 apply 、call、闭包 这三个知识点弄不明白。在之后的工作中,边学边做,也慢慢对它们有了一些了解,今天就来聊一下JavaScript的  apply 、 call  与闭包。

一:apply & call

JavaScript的函数对象都继承了原型链中的apply 与 call 方法。这两个方法的作用就是改变函数在执行时的上下文环境, 什么意思呢,看下面代码:

【JavaScript】apply、call、闭包

打印结果:

【JavaScript】apply、call、闭包

第三十行我们调用 printName函数。这个时候printName函数的上下文环境指的就是全局环境,调用它的对象就是window对象,可以理解成: window.printName();因为当前函数执行的上下文是window,那么函数内部的this就指的是window对象。this.name 指的就是我们声明的全局变量 name = "我"。所以函数调用后打印出来的值是 “我”。

了解了函数的上下文环境,那么我们来看看将代码稍作修改后的情况:

【JavaScript】apply、call、闭包

打印结果:

【JavaScript】apply、call、闭包

当我们使用apply 与 call 方法时,将 obj 对象作为参数传递。此时printName函数的执行上下文或者说调用该函数的对象就是 obj变量。那么函数里的this指的就是 obj变量。最后答应的结果自然是 ”我媳妇“了。

apply 与 call 方法 的区别是两者接收的参数不一样。他们第一个参数相同,都是用来改变上下文环境,后面的参数apply方法接收数组,而call方法接收单个形参。如下:

fnc.apply( obj , arr[] );

fnc.call( obj , x1 , x2 , x3 ... )

二:闭包

将一个函数作为另一个函数的返回值,作为返回值的函数被称为闭包。

在一个函数内部可以访问我们在全局环境声明的变量,但我们在全局环境里却无法访问函数内部的局部变量。如下图,在printName函数中可以访问外部声明的全局变量 name 。外部却无法访问函数内部声明的name2变量;

【JavaScript】apply、call、闭包

【JavaScript】apply、call、闭包

所以我们在函数A内部再次声明一个函数B,函数B因为处于函数A的内部,所已能访问到函数A接收的参数以及声明的局部变量。

在外部调用函数A后,就能拿到作为返回值的函数B。因为函数B获取到函数A的参数和局部变量,对函数A产生依赖关系。那么函数A被调用后在内存空间中就不会立即销毁。(也正是因为函数A在内存中不会被销毁的原因,如果闭包使用不当的话就会产生内存泄漏的问题,所以谨慎使用!)

最后我们就能在外部环境通过函数B 访问到函数A中的变量了。所以闭包是沟通函数内部与外部的桥梁!

转载于:https://my.oschina.net/cc4zj/blog/1609177

相关文章: