一、JS部分:

1、深、浅拷贝的区别?你知道哪些实现深拷贝的方法?

概念:

浅拷贝:只复制指向某个对象的指针,而不复制对象本身,相当于是新建了一个对象,该对象复制了原对象的指针,新旧对象还是共用一个内存块

深拷贝:是新建一个一模一样的对象,该对象与原对象不共享内存,修改新对象也不会影响原对象

两者的区别:假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着改变了,说明这是浅拷贝,如果B没改变,那就是深拷贝

实现深拷贝的方法:

(1)利用递归实现

递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝。

var obj = {   //原数据,包含字符串、对象、函数、数组等不同的类型       name:"test",       main:{           a:1,           b:2       },       fn:function(){                  },        friends:[1,2,3,[22,33]]   }    function copy(obj){        let newobj = null;   //声明一个变量用来储存拷贝之后的内容             //判断数据类型是否是复杂类型,如果是则调用自己,再次循环,如果不是,直接赋值即可,     //由于null不可以循环但类型又是object,所以这个需要对null进行判断        if(typeof(obj) == 'object' && obj !== null){         //声明一个变量用以储存拷贝出来的值,根据参数的具体数据类型声明不同的类型来储存            newobj = obj instanceof Array? [] : {};               //循环obj 中的每一项,如果里面还有复杂数据类型,则直接利用递归再次调用copy函数            for(var i in obj){                  newobj[i] = copy(obj[i])            }        }else{            newobj = obj        }            console.log('77',newobj)      return newobj;    //函数必须有返回值,否则结构为undefined   }     var obj2 = copy(obj)    obj2.name = '修改成功'    obj2.main.a = 100   console.log(obj)   console.log(obj2)

(2)json中的parse和stringify

实现深拷贝:原理就是用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,

缺点:当对象里面有函数的话,深拷贝后,函数会消失。

var arr = ['jack',25,{hobby:'tennise'}];        let arr1 = JSON.parse(JSON.stringify(arr))        arr1[2].hobby='rose'        arr1[0]='rose'        console.log( arr[2].hobby) //tennise        console.log( arr[0]) //jack

(3)Jquery的$.extend:

        var defaults = {name:'张三',age:18,sex:"true",scores:{chinese:70,science:100}};        var options = {name:'李四',age:20,scores:{chinese:98,math:99,english:100}}        var settings = $.extend(true,defaults,options);        console.log(defaults);        console.log(options);        console.log(settings);

2、如何判断一个函数是否作为了构造函数?

使用instanceof 判断:

3、new操作符都做了哪些事情?

new主要做了以下工作:

  1. 先创建了一个新的对象newObj
  2. 将新对象newObj与构造函数通过原型链进行连接
  3. 将构造函数的this绑定到新对象newObj
  4. 根据构建函数返回类型作判断,如果是值类型,返回newObj。如果是引用类型,就返回这个引用类型的对象

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

类数组是一个对象,属性名使用数字,并且带有length属性。

let objArr = {0:"name",1:"age",2:"color",length:3};

类数组转换为数组的方法:

1、slice函数

let arr1 = Array.prototype.slice.call(objArr);

2、扩展运算符 只能把有iterator接口的类数组转为数组;

let Str = 'hello';let arr = [...Str];console.log(arr);

3、Array.form();es6新增的方法

let arrr = Array.from(objArr);

5、如图,连续多次bind()的结果是什么?

3 3 在js中,多次bind()只有第一次绑定会生效。

6、说说什么是防抖和节流?尝试自定义防抖函数debounce和节流函数throttle” />

8、ES6箭头函数和普通函数有哪些区别?

1.箭头函数没有phototype,所以箭头函数本身没有this

2.箭头函数的this在定义时指向外层第一个普通函数,如果外层没有普通函数,则指向window

3.箭头函数本身的this指向不能改变,但可以修改它要继承的对象this

4.箭头函数this指向全局,不能调用arguments

5.箭头函数this指向普通函数时,使用arguments继承于该普通函数

6.使用new调用箭头函数会报错,因此箭头函数没有constructor

7.箭头函数不支持new.target

8.箭头函数不支持重命名函数参数,普通函数参数支持

9、如何使用js计算一个html页面中有多少种标签?

10、写出下面代码的输出结果:

(1)提示: 变量提升

答案:undefined 10

(2)提示:函数提升

答案:

11、map方法和forEach的不同之处?

forEach() 方法不会返回执行结果,而是undefined。

也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回。

二、Vue2部分

1、v-show和v-if的主要区别 ?

v-show指令:元素始终被渲染到HTML,它只是简单的伪元素设置css的style属性,当不满足条件的元素被设置style=“display:none”的样,是通过修改元素的的CSS属性(display)来决定实现显示还是隐藏
v-if指令:满足条件是会渲染到html中,不满足条件时是不会渲染到html中的,是通过操纵dom元素来进行切换显示

2、vue2中的data是什么类型” />ES6Set去重(ES6中最常用)

function unique (arr) {  return Array.from(new Set(arr))}var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];console.log(unique(arr))//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]

不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。

二、利用for嵌套for,然后splice去重(ES5中最常用)

function unique(arr){                    for(var i=0; i

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

2、用js实现一个方法:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次,找出那个只出现一次元素。

var singleNumber =function(nums){     //声明一个空对象用于记录     var obj={};    for(var i=0;i<nums.length;i++){    //此时读取对象的属性需要用[]if(!obj[nums[i]]){    obj[nums[i]] =1;}else{    obj[nums[i]]+=1;}   //取出属性值为1的   for(var j in obj){   if(obj[j] ==1)   return j;}}