日报_29

164 阅读5分钟

2020年6月1日 星期一

Being a kid is a wonderful thing. Second it is over, you start wishing you could have it back again.

戊戌年, 丁巳月 甲子日,儿童节,首先祝愿忙着生活的大朋友,童心不泯,祝愿没有长大的小朋友喜乐无忧,致我们逝去的童年!!🌹🌹🌹六一儿童节快乐。

今天呢主要深入学习了闭包和this的指向问题给大家分享一下学习心得。

闭包

我们知道在前端开发中闭包是一个很重要的知识点,就算是在面试中呢也是问道的高频面试题,之前我对‘闭包’的理解呢就是:函数嵌套函数,在函数外部可以访问函数内部的变量;对闭包呢也是用的比较少,就算是自己写过闭包也不清楚;所以呢今天也是想深入的学习一下闭包。

闭包的定义:

闭包是一个函数与作用域环境(即** 词法环境 **)形成的闭包

闭包的理解:

广义的闭包:
    1.他是一个函数 
    2.这个函数能访问到函数外部的状态(也称函数外部的变量)
狭义的闭包:
    函数嵌套函数,并且内部函数通过return返回到外部,外部可以访问内部函数的变量
<script>
    // 自由变量: 自由变量:就是在函数外部定义的,并且在函数内部可以访问到的变量就叫自由变量
    var index = 1;

    // 闭包的实际应用举例
    function getIndex()
    {
        console.log(index);
    }
    getIndex();
</script>

闭包的特点:

1、当函数在定义时的词法作用域以外调用时,闭包使得函数可以继续访问其定义时的词法作用域

2、闭包中自由变量长期驻留内存,长期驻留内存中的变量如果处理不当,会导致内存泄露,不用的
话要将闭包置为null
可以隔离作用域,模拟块级作用域

3、闭包可以阻止内存空间的回收

4、只要使用了回调函数,实际上就在使用闭包

闭包的实际应用举例

  • 作用域链:通过在当前函数内部查找要访问的变量,如果有则访问,没有则向上一级查找此变量,上级有则访问之,没有再再往上上一级查找,以此类推,直到找到全部window下有没有,有则访问,没有些报错。

是否有点像原型链的查找呢????非常像

闭包应用举例:  计数器   改变页面字号   定时器累加
        /** 计数器 */
    //功能:递增,递减,获取递增或递减之后的值
var Counter=function() {
    //私有变量
    var num=0;
    //私有函数
    var changeValue=function(n) {
        return num+=n;
    }
   return {
       //增
       increment:function() {
            changeValue(1)
       },
       //减
       decrement:function() {
            changeValue(-1)
       },
       //获取值
       getValue:function() {
           return num;
       }
   }
}
        /** 改变页面字 */
    function setSize(size) {

   return function() {

     document.body.style.fontSize=size+'px'
   }
}

var size12=setSize(12);

var size40=setSize(40)

var size50=setSize(50);
        /** 定时器累加 */
    //要求每隔1秒打印1,2,3,.....10

  //setTimeout是异步执行的,异步队列

/*
  for(var i=1;i<=10;i++) {
     
     (function(j) {
        setTimeout(function() {
            console.log('i=j的值:',j)
        },2000*j)
     })(i)

  }
  console.log('最后打印:',i)
  */
   for(let i=1;i<=10;i++) {
    
        setTimeout(function() {
            console.log('i的值:',i)
        },1000*i)
  }

this指向

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,

实际上this的最终指向的是那个调用它的对象

难道这句话真的正确吗?????

网上是这么说得但实际上还是不准确得;

我们接下来讨论一下这个话题

在js中直接输出this

 console.log(this); // Window
 
 这个this是在全局中环境中得

在DOM中的this

<button class="btn">改变当前按钮背景色</button>

<script>
 var btn=document.querySelector('.btn')
 btn.onclick=function() {
     console.log(this===btn)
     this.style.background='#f00'
 }
</script>

定时器中的this

<script>
  var value='React'

    var obj={
        value:'vuejs',
        getValue:function() {
           // var _this=this;
            setTimeout(()=>{
                console.log(this)
                console.log(this.value)
            },2000)
        }
    }

    obj.getValue()
</script>

JS中的this--在对象内


<script>
    var value='React'

    var obj={
        value:'vuejs',
        getValue:function() {
            //this
            //console.log('this===obj:',this===obj)
            var that=this;
            function getValue2() {
                console.log('obj内部this:',this.value)
            }

            getValue2()

            return this.value;
        }
    }

    obj.getValue()

</script>

JS中的this--在构造函数内

<script>
   function Fn(name='张三',age=0) {
       this.name=name
       this.age=age
       //指向实现化的对象,分别:this===f1  //true
       console.log('this:',this)
   }

  var f1=new Fn('薰悟空',20)
  var f2=new Fn('小猪猪',18)

  console.log('f1:',f1.name)
  console.log('f1:',f1.age)

  console.log('f2:',f2.name)
  console.log('f3:',f2.age)
</script>
this和作用域不一样,作用域是声明的时候就定下来了,this是在调用的时候才确定下来
1、默认绑定
function test() {
    console.log(this) //this指向window
}

(自己执行自己)fn() (默认情况下的隐式执行) this指向window
(严格模式下指向undefined,不指向)window



2、隐式绑定,谁调用指向谁
    const obj = {
        name:'joy',
        getName(){
            console.log(this); //this指向obj
            console.log(this.name); //joy
        }
    };
    obj.getName();
    当然也可以通过call,apply,bind来改变this指向问题
    现在也不会去考虑this问题,因为ES6出了一个箭头函数,调用前this是什么函数里面的this就是什么,常用的就是箭头函数

3、显示执行:
(函数的方法执行)
function fn(){
       console.log(this.a)
   }
    var a = 10;
    var obj = {
        a : 20,
        b : fn,
    }
    obj.b();//  返回值20;this指向的是fn引用的地址
//fn作为一个函数本身是一个对象,在内存中所占据的空间依然是一个地址,
//在用obj.b(),执行这个函数时执行的是一个引用,函数本身就是一个引用,
//当把fn复制给obj中的b时,复制的是一个引用地址=》浅拷贝,当我早使用obj.b()
//执行函数,用obj找到那个引用位置,这个时候,函数引用的位置被obj所找到,被obj
//执行,那么此时函数里的this就指向找到我位置的那个对象,也就是fn被哪个对象所
//执行,此时,fn就指向谁

先天高手:谁执行了this所在的函数,this就是谁

后天高手:就是通过call,apply,bind改变了this的指向