面试题day01

#### 1.vue2的生命周期?

```js
是从Vue实例创建、运行、到销毁期间,伴随着的各种事件,这些事件统称为生命周期。
2.生命周期函数分类:
1.创建的生命周期函数:
beforeCreate:实例刚在内存中被创建出来,此时还没有初始化好data和methods属性
created: 实例已经在内存中创建出来,此时的data和methods以及创建完成,但是还没有开始编译模板
mounted: 已经将编译好的模板,挂载到了页面指定的容器中显示.
运行期间的生命周期函数:
beforeUpdate状态更新之前执行此函数,此时data中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点
updated: 实例更新完毕之后调用函数,此时data中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了。
销毁期间的生命周期函数:
beforeDestory: 实例销毁之前调用,在这一步,实例仍然完全可用。
destroyed: Vue实例销毁之后调用。调用后,Vue实例指示的所有东西都会解绑,所有事件监听器会被移除,所有的子实例也会被销毁,
```

#### 2.methods和计算属性有什么区别?

```js
1.计算属性和methods的执行结果都是相同的
2.当计算属性没有依赖data的数据时,第一次使用计算属性时,会把第一次的结果进行缓存,后面再次使用计算属性,都会去第一次的结果中进行查找。
3.methods方法,每调用一次,就会触发一次
4.计算属性的用法与data中的数据用法一样,因此计算属性在使用时,不加()
5.methods方法在调用时,()可加可不加
6.计算顺序具有缓存功能,methods方法没有
1、既然计算属性computed都叫属性了,那么他就是可以当作属性来使用,可以修改;而method是当作方法来使用,它也可以获取值,只不过是return返回值

2、computed有getter和setter进行赋值.而method不行;

3、计算不行不能传值,虽然你在定义的时候看上去是方法computed(){},但是他不能像方法那样可以进行传递参数

4、computed如果数据不变是可以进行缓存的,而方法不行只要是在页面中使用了方法,那么使用几次久会调用方法几次,而computer不会
具体讲解原理层的区别
vue对methods的处理比较简单,只需要遍历methods配置中的每个属性,将其对应的函数使用bind绑定当前组件实例后复制其引用到组件实例即可。
//vue实例对象伪代码
function Vue(options){
    //  其他操作...
    //对于vue中的methods中的方法进行遍历,把每个方法都放到vue实例中,方便我们使用this.XX方法名字
    Object.entries(methods).forEach(([methodName,fn)=>{
        this[methodName]=fn.bind(this)
    })
}
new Vue(vnode.componentOptions)
```

**[vue的数据响应原理](https://blog.csdn.net/weixin_41277748/article/details/115680611?spm=1001.2014.3001.5501%EF%BC%89%EF%BC%8C)**

#### [虚拟DOM的实现原理与优缺点](https://blog.csdn.net/zyq51/article/details/108741558?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-108741558-blog-118694644.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-108741558-blog-118694644.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=11)

#### [render函数介绍](https://blog.csdn.net/qq78827534/article/details/80792514?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166559388216781432988361%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166559388216781432988361&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-80792514-null-null.142^v53^control,201^v3^control_1&utm_term=render&spm=1018.2226.3001.4187)

#### [JSX 语法详解](https://blog.csdn.net/web00_11/article/details/121315226?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166559398616781432997287%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166559398616781432997287&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-121315226-null-null.142^v53^control,201^v3^control_1&utm_term=JSX%E8%AF%AD%E6%B3%95&spm=1018.2226.3001.4187)

#### 3.闭包:什么是闭包、闭包的作用、闭包的解决

```js
学习闭包我们要清楚函数作用域、内存回收机制、作用域继承。
1.1 函数作用域
作用域我们可以认为它是一个封闭的盒子,只让它在这个盒子里面进行操作,也可以称这个盒子为独立作用域。在js中,一个函数要执行时就会在内存里面创建一个独立作用域————封闭的盒子。

<script>
   //函数执行
  function fn(){
    var a =1;
}
fn();
//函数执行完毕
</script>
```

比如在函数中第一一个变量,只能在函数这个独立作用域中使用(也就是封闭的盒子)。只要跳出这个作用域,就找不到该变量了。

而且函数执行完毕之后,这个独立作用域或(封闭的盒子)就会删除。有一种情况下这个封闭的盒子是不会删除的,那就是“闭包”,后面会讲到。

#### **1.2 内存回收机制**

 内存回收机制就是不在用到的内存空间,系统会自动进行清理出空间提供给其他程序使用。那回收的前提是什么呢? 

 ![img](https://img-blog.csdnimg.cn/img_convert/e5903a32d24cc2cb8d33197d4dff43af.webp?x-oss-process=image/format,png)

 内部函数引用外部的函数的变量,外部函数执行完毕,作用域也不会删除。从而形成了一种不删除的独立作用域。

某一个变量或者对象被引用,因此在回收的时候不会释放它,因为被引用代表着被使用,回收机制不会对正在引用的变量或对象进行回收的。

#### **1.3 作用域继承**

所谓的作用域继承,就像是儿子可以继承父亲的财产一样。比如我这里有一个大的盒子作为一个父级的作用域,然后在这个大的盒子里边放一个小的盒子,作为子作用域。我们规定可以在小盒子中获取到大盒子中的东西,大盒子不能获取小盒子里的东西就称为作用域继承。

```js
<script>
 function fn(){
    var a = 5;
    return function (){
        console.log(a);
    }
}
</script>
```

在 JS 中,道理是一样的,在一个函数里边我们再声明一个函数,内部函数可以访问外部函数作用域的变量,而外部的函数不能获取到内部函数的作用域变量。

那好,上边的这几个概念理解了之后,什么是闭包对你来说已经不是什么问题。

什么是闭包,那就是在一个函数里边再定义一个函数。这个内部函数一直保持有对外部函数中作用域的访问(小盒子可以一直访问大盒子但大盒子不能访问小盒子)。

```js
<script>
    function fn(){
    var a= 5;
    return function(){
        consolo.log(a);
    }
}
</script>
```

 函数执行,形成一个独立作用域,保护里边的私有变量不受外界的干扰,除了保护私有变量外,还可以存储一些内容,这样的模式叫做闭包。 

2、闭包的作用是什么
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

作用是:通过一系方法,将函数内部的变量(局部变量)转化为全局变量

3、闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

```js
 function f1(){

    var n=999;

    nAdd=function(){

alert(n+=1);  

}

    function f2(){
alert(n);
}

    return f2;

  }

  var result=f1();

  result(); //999

  nAdd();//1000

  result(); //1001

```

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。 其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个操控者,可以在函数外部对函数内部的局部变量进行操作。

4、使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

5、解决方案
当点击事件执行的时候,就会在独立作用域查找 i 的值,此时独立作用域没有 i ,就回去全局作用域查找,此时全局作用域的 i 已经被改变。所以说,要创建一个私有作用域的 i 。
 方法一: 

```js
<script>
    // 方法一: 自定义属性
    for(var i = 0; i < 10; i++){
        inputs[i].myIndex = i;
        inputs[i].onclick = function(){
            alert(this.myIndex);
        }
    }
</script>
```

 方法二:

```js
<script>
    var len = input.length;    
    for(let i = 0; i < 10; i++){
       inputs[i].onclick = function(){
           alert(i);
       }
    }
</script>
```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值