闭包,立即执行函数(IIFE),this指向

闭包概念->闭包作用->立即执行函数->for in例子如果每次输出不同的值( 闭包,定时器第二个变量,promise/let)->在jquery中的使用

由于javascript中特有的作用域,函数中的局部变量不能够被外部获得或使用,而函数内部可以使用外部的全局变量,并且javascript的垃圾回收机制会在function执行过后自动销毁函数内部的变量。

这就是我们就需要运用闭包来解决这个问题,在我看来闭包的主要作用是:

    1.使得函数内部的变量能够安全的被外部获取

    2.使得函数在执行后,内部变量依旧被保存在内存中,不会被自动销毁(使用后要用null销毁,否则会占用内存)

    3.可以将函数内部的变量私有化

三个经典场景:

    1.通过循环给每一个dom节点绑定事件,用闭包把循环所需的i封装起来

    2.封装变量

    3.延长局部变量寿命

function foo(){
  var a = 0;
  function bar(){
   return a++;
  }
  return bar;
}
var Fooo = foo();

如上面的代码所示,当Fooo在外部调用了foo()之后,bar()被保存了下来,由于bar()内部调用了父级作用域里的变量a,所以父级function在函数结束后foo()不会被自动销毁,从而形成了闭包。

总的来说闭包就是创建了内部变量,不能被外部随意的修改,但是能够通过特定的接口来获取。一般来说闭包会和立即执行函数配合使用,因为立即执行函数能够对函数实现封装,从而达到避免污染全局变量的目的。立即执行函数可以在函数前用!+ - =等符号来实现,但是建议使用双括号包裹来实现,从而实现块级结构,再多人开发中不会互相影响。jquery中的封装便是使用了闭包和立即执行函数的思想(Immediately Invoked Function Expression).

举例说明:

如果我们要实现,从0到4每一秒输出一个数字的效果:

for(var i=0; i<5; i++){
 setTimeOut(function(){
  console.log(i);
 },1000)
)

如果我们用这种方法来实现的话,输出结果将是5->5,5,5,5,5。第一个5是由于for语句的执行顺序,而其他几个数字是由于公共变量i一直在被修改,当1000ms后输出的时候其实i都是5。要解决这一问题,我们有五种解决方法: 1.闭包 2.setTimeOut自带参数 3.用let实现块级作用域 4.用es6中的promise 5.es6中async wait

闭包:

for(var i=0; i<5; i++){
 (function(j){
   setTimeOut(function(){
    console.log(j);
   },1000);
 })(i);
}

setTimeOut:

for(var i=0; i<5; i++){
 setTimeOut(function(pram){
  console.log(pram);
 },1000,i)
}

let:

for(let i=0; i<5; i++){
 setTimeOut(function(){
  console.log(i);
 },1000)
)

es6中的let语句所声明的i是局部变量,只在本轮循环内有用,每一轮都是一个新的变量i,所以互相之间不影响。


THIS指向问题

函数调用(指向window) 对象方法(对象) 构造函数(实例化出来的对象) 计时器调用(全局) 匿名函数(window) 

原型中的this指向调用他的对象不指向本身

阅读更多
个人分类: javascript
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭