vue面试三之JS基础之什么是闭包函数,有啥用?、JS基础之防抖和节流 区别及实现方式?、描述下 vue 从初始化页面--修改数据--刷新页面 UI 的过程?

1. JS基础之什么是闭包函数,有啥用?

var i=10;
function add1(){
   alert(i);
   i++;
}
function add2(){
   var j=100;
   alert(j);
   j++;
}

//测试:
//    add1(); //10
//    add1(); //11
//    add1(); //12
//
//    add2(); //10
//    add2(); //10
//    add2(); //10

为什么呢 原因很简单
i 是全局变量,只有页面关闭的时候,才会被GC回收;
j 是局部变量,函数执行完毕后就 被GC 回收;
问:有没有办法将j 变成"全局变量"呢?
有,将j写在外面(脑子有粑粑)
答案:闭包

function add3(){
  var j=10;
  return function(){
   alert(j);
   j++;
  }
}

//测试:
//   var bibao=add3();
//   bibao(); //10
//   bibao(); //11
//   bibao();//12

执行add3()的时候,根据代码,会返回函数体(是一个函数对象) ----------------console.log(bibao)
// 返回值:function(){
//    alert(j);
//    j++;
//   }
再加上一个括号()(让函数体,函数对象执行),就可以执行了--------------------console.log(bibao()))
//  10


// js调用函数时加括号与不加括号的区别
// 不加括号返回函数体
// 加括号返回函数体执行的结果

ok,这个时候大家应该知道闭包是怎么用的了,那在vue中,闭包都在那些地方用过?
1 Vue的computed使用闭包函数传值

<script type="text/x-template" id="hello-world-template">
    <div>
      <p>Original message: "{{ message }}"</p>
      <p>Computed reversed message: "{{ reversedMessage }}"</p>
      <p>Computed reversed message: "{{ reversedMessage1(2) }}"</p>
	</div>
</script>
<div id="example"></div>

<script>
var vm = new Vue({
    el: '#example',
    template: '#hello-world-template',
    data: {
      message: 'Hello'
    },
    computed: {
      reversedMessage: function() {
        return this.message.split('').reverse().join('')
      },
      reversedMessage1: function() {
        return function reversedMessageget(y) {
          return this.message.split('').reverse().join('')+'___'+y;
        }
      },
    },
    mounted(){
      console.log(this)
    }
  })
</script>

2 data选项使用闭包返回

<script type="text/x-template" id="hello-world-template">
    <div>
       <button @click="add">count</button>
	</div>
</script>
<div id="example"></div>

<script>
var vm = new Vue({
    el: '#example',
    template: '#hello-world-template',
    // 不使用闭包的情况
    data: {
      count: 1
    }
    // 使用闭包的情况
     data(){
       return {
           count: 1
       }
    },
    method:{
       add(){
          this.count++
       }
    }
  })
</script>


// 给当前vue文件封装成一个组件,并且在别的地方引用多次
// 如果不使用闭包:
// count 为全局变量,随便点击一个组件,其余两个组件的值都会相加
// 如果使用闭包:
// 点那个,那个就会增加。 这里使用闭包,就是为了***不污染全局***

2. JS基础之防抖和节流 区别及实现方式?

防抖:在第一次触发事件时,不立即执行函数,而是给出一个期限值(比如200ms),然后:
1 如果在200ms内没有再次触发滚动事件,那么就执行函数
2 如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时

防抖非常好的例子:

/*
* fn [function] 需要防抖的函数
* delay [number] 毫秒,防抖期限值
*/
function debounce(fn,delay){
    let timer = null //借助闭包,复习一下,避免全局污染
    return function() {
        if(timer){
            clearTimeout(timer) //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
            timer = setTimeout(fn,delay) 
        }else{
            timer = setTimeout(fn,delay) // 进入该分支说明当前并没有在计时,那么就开始一个计时
        }
    }
}

window.onscroll = debounce(showTop,1000) // 为了方便观察效果我们取个大点的间断值,实际使用根据需要来配置

// window.onscroll  监听滚动条滚动 
// showTop 监听滚动条滚动后执行的方法

显而易见,读完这个代码以后,读者肯定会发现一个问题就是:如果我一直滑动滚动条,那这个代码这不就一直执行不了
这就是防抖的缺点:如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟

节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
节流经典代码:

//节流throttle代码:
function throttle(fn) {
    let canRun = true; // 通过闭包保存一个标记
    return function () {
         // 在函数开头判断标记是否为true,不为true则return
        if (!canRun) return;
         // 立即设置为false
        canRun = false;
        // 将外部传入的函数的执行放在setTimeout中
        setTimeout(() => { 
        // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
        // 当定时器没有执行的时候标记永远是false,在开头被return掉
            fn.apply(this, arguments);
            canRun = true;
        }, 500);
    };
}

function sayHi(e) {
    console.log(e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(sayHi));

3. 描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?

当 Vue 进入初始化阶段时,一方面 Vue 会遍历 data 中的属性,并用 Object.defineProperty 将它转化成 getter/setter 的形式,实现数据劫持(暂不谈 Vue3.0 的 Proxy);另一方面,Vue 的指令编译器 Compiler 对元素节点的各个指令进行解析,初始化视图,并订阅 Watcher 来更新视图,此时 Watcher 会将自己添加到消息订阅器 Dep 中,此时初始化完毕。
当数据发生变化时,触发 Observer 中 setter 方法,立即调用 Dep.notify(),Dep 这个数组开始遍历所有的订阅者,并调用其 update 方法,Vue 内部再通过 diff 算法,patch 相应的更新完成对订阅者视图的改变。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值