【Js+Vue考核总结】

一、JS部分
1.深、浅拷贝的区别?你知道哪些实现深拷贝的方法?

深拷贝:深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象(新旧对象不共享同一块内存),且修改新对象不会影响原对象(深拷贝采用了在堆内存中申请新的空间来存储数据,这样每个可以避免指针悬挂)

浅拷贝:如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址(新旧对象共享同一块内存),所以如果其中一个对象改变了这个地址,就会影响到另一个对象(只是拷贝了指针,使得两个指针指向同一个地址,这样在对象块结束,调用函数析构的时,会造成同一份资源析构2次,即delete同一块内存2次,造成程序崩溃)

区别:假如B复制了A,如何区分深拷贝和浅拷贝,最简单的方法就是,当修改B的时候,A是否跟着变化,如果A也发生了变化,那就是浅拷贝,如果A没有发生变化,那就属于深拷贝了。

(1)暴力解法,使用递归函数

这种解法的思路就是对一个对象或数组的每一个元素进行遍历,如果元素属于基本数据类型,就直接对其进行拷贝;如果一个元素还是对象或者数组的话,就对该元素进行进一步的遍历。以此类推,直到找到其中的元素属于基本数据类型为止,然后再进行拷贝。实现代码如下:

function deepClone1(obj) {
            //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
            var objClone = Array.isArray(obj) ? [] : {};
            //进行深拷贝的不能为空,并且是对象,因为null也是object类型,所以单独做判断
            if (obj && typeof obj === "object" &&obj!=null) {
                for (var key in obj) {
                    //判断obj中是否存在key属性
                    if (obj.hasOwnProperty(key)) {
                        if (obj[key] && typeof obj[key] === "object") {
                           objClone[key] = deepClone1(obj[key]);
                        } else {
                           objClone[key] = obj[key];
                        }
                    }
                }
            }
            return objClone;
        }
        var obj1={
            name:'xihuan',
            info:{
                age:19,
                sex:'女'
            }
        }
        var obj2=deepClone1(obj1);
        obj1.name='xixi';
        obj1.info.age=18;
        console.log(obj1);
        console.log(obj2);

在这里插入图片描述 (2). 通过JSON方法实现深拷贝

这就是利用之前提到的JSON的JSON.parse()和JSON.stringify()的两个方法实现。

        let arr=[1,2,{name:'sehun'},[3,4]];
        let arr2=JSON.parse(JSON.stringify(arr));
        arr[0]=100;
        arr[2].name='吴世勋';
        arr[3][0]=300;
        console.log(arr,arr2);

在这里插入图片描述(3).Jquery的$.extend:

        var a = [0,1,[2,3],4];
        b = $.extend(true,[],a);
        a[0] = 1;
        a[2][0] = 7;
        console.log(a);   //  [1,1,[7,3],4];
        console.log(b);   //  [0,1,[2,3],4];

        //$.extend参数:
        //第一个参数是布尔值,是否深复制
        //第二个参数是目标对象,其他对象的成员属性将被附加到该对象上
        //第三个及以后的参数是被合并的对象`

2.如何判断一个函数是否作为了构造函数?
使用instanceof 判断:在这里插入图片描述
3.new操作符都做了哪些事情?

在JavaScript中,new操作符用于创建一个给定构造函数的实例对象 new操作符主要做了下面工作:

创建一个新的对象obj
将对象与构建函数通过原型链连接起来
将构建函数中的this绑定到新建的对象obj上
根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理

4.什么是类数组?列举你知道的类数组转为数组的方法。

概念:

判断类数组的标准主要有以下几点:

类数组是一个对象。
类数组含有长度属性,并且该属性值是一个正整数

var s={ 0:'exo', 1:'blackpink', 2:'asepa', length:3 }

方法:
(1)、利用apply或者call方法:

const a1 = Array.prototype.slice.call(s)
Array.isArray(a1)//true 

(2)、ES6中的Array.from()

const a2 = Array.from(s) 
Array.isArray(a2)//true

(3)、ES6扩展运算符

 const a3 = [...s]
 Array.isArray(a3) //true

5.如图,连续多次bind()的结果是什么?
在这里插入图片描述

答案是3,原因在于:
bind 绑定之后会返回新的函数,所以代码我们可以看成 ‘新函数’.bind(fiv),这个’新函数’里面还有’新函数’,‘新函数’里面还有’新函数’,知道有这些的话,我们只看最外层的一个就好了,当 func()之后此时最外层的’新函数’的this指向是fiv(5),然后接着执行里面的’新函数’,接着this从fiv(5)指向了sed(4),,一直这样,最后执行到bar.bind(foo),此时this已经指向foo(3)了,所以输出的结果是3,多次绑定bind只是一直在改变this的指向,最终还是变回第一次绑定的this。所以bind多次绑定是无效,只有第一次有效果

6.说说什么是防抖和节流?尝试自定义防抖函数debounce和节流函数throttle?
(1). debounce()防抖函数🍊

某个函数在短时间内只执行最后一次。

function debounce(fn,delay = 200) {
    if(typeof fn !== 'function'){
        return TypeError('fn is not a function')
    }
    let lastfn = null

    return function(...args) {
        if(lastfn){
            clearTimeout(lastfn)
        }
        lastfn = setTimeout(() => {
            lastfn = null
            fn.call(this,...args)
        },delay)
    }
}

(2). throttle()节流函数🍊

某个函数在指定时间段内只执行第一次,直到指定时间段结束,周而复始。

function throttle(fn, delay = 200) {
    let flag = false
    return function (...args) {
        if (!flag) {
            flag = true
            setTimeout(() => {
                flag = false
                fn.call(this,...args)
            },delay)
        }
    }
}

9.如何使用js计算一个html页面中有多少种标签?
在这里插入图片描述10.写出下面代码的输出结果:
(1)提示: 变量提升
在这里插入图片描述答案:undefined 10
(2)提示:函数提升
在这里插入图片描述答案:
在这里插入图片描述11. map和forEach的区别?

共同点:

    1.都是循环遍历数组中的每一项。
    2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前项的索引index,原始数组input。
    3.匿名函数中的this都是指Window。
    4.只能遍历数组.

区别:

    forEach()没有返回值,而map有返回值,map的回调函数中支持return返回值;return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了)

二、Vue部分
1.v-show和v-if的主要区别?

函数类型
因为Vue组件要实现重复利用,需要保证数据相互独立,函数类型每次都返回一个新的对象,可以防止各个组件之间的数据污染

2.vue2中的data是什么类型?解释为什么这样设计。

data是一个函数类型,因为需要重复利用,所以需要相互独立。

3.vue-router传参的方式有哪些?

(1)、router-link路由导航方式传参

(2)、调用$router.push实现路由传参

(3)、通过路由属性name匹配路由,再根据params传递参数

(4)、通过query来传递参数

4.你知道哪些vue-router的钩子函数,说说他们都是什么时候触发的?

  • 生命周期钩子函数(9个)
  • beforCreate在实例初始化之后,数据观测 (data observer) 和 event/watcher事件配置之前被调用。 created在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测(data observer),
    属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$ el 属性目前不可见。
  • beforeMount在挂载开始之前被调用:相关的 render 函数首次被调用。 mounted el 被新创建的 vm.el替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当mounted 被调用时 vm.$el
    也在文档内。
  • beforeUpdated数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
  • updated由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
  • activated keep-alive组件激活时调用。该钩子在服务器端渲染期间不被调用。
  • deactivated keep-alive组件停用时调用。该钩子在服务器端渲染期间不被调用。
  • beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。
  • destroyed Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

5.vue组件之间的通信方式有哪些?

父组件→子组件:利用props属性
子组件→父组件:利用自定义事件,使用$ emit()发送事件和要传递的数据
父组件访问子组件:利用$ c h i l d r e n 或 者 children或者 children$ r e f s 属 性 进 行 访 问 , 注 意 : refs属性进行访问,注意: refs访,:$ refs默认是一个空对象,需要在子组件上绑定res属性,来告诉父组件要访问的是哪个子组件
子组件访问父组件 :利用$ parent,也可以使用$root直接访问根组件

6.简述vue生命周期

vue每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁,这就是一个组件所谓的生命周期。

7.什么是SPA?说说SPA和MPA的优缺点

SPA(SinglePageApplication)单页面应用,顾名思义,就是只有一个主页面,一开始只需要加载一次js,css等资源,对各个功能模块进行组件化,所以单页面应用的跳转,就是切换组件,只局部刷新,适合移动应用开发;仅在Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载
MPA(MutiPage Application)多页面应用,是有多个独立页面的应用。每个页面必须重复加载相关资源,跳转页面会整体刷新。
SPA优点: 页面切换快
缺点: 首屏时间稍慢,SEO差
MPA优点: 首屏时间快,SEO效果好
缺点: 页面切换慢

8.简述Vue2响应式原理。

当把一个普通的JavaScript对象传入Vue实例作为data选项,Vue会遍历此对象所有的property,并使用Object.defineProperty把这些property转为setter/getter,这些getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。
其次,每个Vue实例都对应着一个watcher实例,他会在组件渲染的时候把接触过的数据property记录为依赖。之后如果依赖项的setter触发,会通知watcher重新渲染响应的组件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值