JavaScript相关面试题2:1.深拷贝和浅拷贝区别;2. [“1“,“2“,“3“].map(parselInt)的返回值;3.预防按钮的重复点击

简介: 解决方案1.控制按钮,在短时间内被多次点击,第一次以后的点击无效。2.控制按钮,在点击按钮触发的请求响应之前,再次点击无效。3.配置特殊的URL,然后控制这些URL请求的最小时间间隔。如果再次请求跟前一-次请求间隔很小,弹窗二次提示,是否继续操作。防止无意识复点击按钮给按钮添加控制,在control 毫秒内,第一次点击事件之后的点击事件不执行。

文章目录

深拷贝浅拷贝有什么区别?怎么实现深拷贝?

["1","2","3"].map(parselInt)的返回值是什么?

怎么预防按钮的重复点击?

深拷贝浅拷贝有什么区别?怎么实现深拷贝?

浅拷贝

浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝

如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址

即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址

下面简单实现一个浅拷贝


function shallowClone(obj) {

   const newObj = {};

   for(let prop in obj) {

       if(obj.hasOwnProperty(prop)){

           newObj[prop] = obj[prop];

       }

   }

   return newObj;

}

1

2

3

4

5

6

7

8

9

在JavaScript中,存在浅拷贝的现象有:

Object.assign

Array.prototype.slice(), Array.prototype.concat()

使用拓展运算符实现的复制


深拷贝

深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

常见的深拷贝方式有:

_.cloneDeep()

jQuery.extend()

JSON.stringify()

手写循环递归


_.cloneDeep()


const _ = require('lodash');

const obj1 = {

   a: 1,

   b: { f: { g: 1 } },

   c: [1, 2, 3]

};

const obj2 = _.cloneDeep(obj1);

console.log(obj1.b.f === obj2.b.f);// false

1

2

3

4

5

6

7

8

jQuery.extend()


const $ = require('jquery');

const obj1 = {

   a: 1,

   b: { f: { g: 1 } },

   c: [1, 2, 3]

};

const obj2 = $.extend(true, {}, obj1);

console.log(obj1.b.f === obj2.b.f); // false

1

2

3

4

5

6

7

8

JSON.stringify()


const obj2=JSON.parse(JSON.stringify(obj1));


1

2

循环递归


function deepClone(obj, hash = new WeakMap()) {

 if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作

 if (obj instanceof Date) return new Date(obj);

 if (obj instanceof RegExp) return new RegExp(obj);

 // 可能是对象或者普通的值  如果是函数的话是不需要深拷贝

 if (typeof obj !== "object") return obj;

 // 是对象的话就要进行深拷贝

 if (hash.get(obj)) return hash.get(obj);

 let cloneObj = new obj.constructor();

 // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身

 hash.set(obj, cloneObj);

 for (let key in obj) {

   if (obj.hasOwnProperty(key)) {

     // 实现一个递归拷贝

     cloneObj[key] = deepClone(obj[key], hash);

   }

 }

 return cloneObj;

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

区别



从上图发现,浅拷贝和深拷贝都创建出一个新的对象,但在复制对象属性的时候,行为就不一样

浅拷贝只复制属性指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,修改对象属性会影响原对象


[“1”,“2”,“3”].map(parselInt)的返回值是什么?

首先整个题目考校的是两个函数,和一个字符串转数字的概念

1.数组的map函数,接受三个参数,当前值,当前索引,当前数组。

2. parselnt接受两个参数,需要转换的字符串,基数(基数取值范围2~36)

3. 根据上面的两个函数的解释,我们可以发现实际上,上面的[‘1’,‘2’,‘3’].map(parseInt) 其实就是等价于下面的代码。


['1','2','3'].map((item, index) => {  

   return parseInt(item, index)  

})  

//  parseInt('1', 0)  1  

//  parseInt('2', 1)  NaN  

//  parseInt('3', 2)  NaN

1

2

3

4

5

6

4.如果我们需要返回1,2,3需要怎么办?


function parseIntFun(item) {  

   return parseInt(item, 10)  

}  

['1','2','3'].map(parseIntFun)  

//  parseInt('1', 10)  1  

//  parseInt('2', 10)  2  

//  parseInt('3', 10)  3

1

2

3

4

5

6

7

怎么预防按钮的重复点击?

先看看在那些场景会导致重复请求:

1.手速快,不小心双击操作按钮。

2.很小心的点击了一次按钮,因为请求响应比较慢,页面没有任何提示,怀疑上次点击没生效,再次点击操作按钮。

3.很小心的点击了一次按钮, 因为请求响应比较慢,页面没有任何提示,刷新页面,再次点击操作按钮。


解决方案

1.控制按钮,在短时间内被多次点击,第一次以后的点击无效。

2.控制按钮,在点击按钮触发的请求响应之前,再次点击无效。

3.配置特殊的URL,然后控制这些URL请求的最小时间间隔。如果再次请求跟前一-次请求间隔很小,弹窗二次提示,是否继续操作。


防止无意识复点击按钮

给按钮添加控制,在control 毫秒内,第一次点击事件之后的点击事件不执行。


<template>

   <button @click="handleClick"></button>

</templage>

<script>

export default {

   methods: {

       handleClick(event) {

           if (this.disabled) return;

           if (this.notAllowed) return;

           // 点击完多少秒不能继续点

           this.notAllowed = true;

           setTimeout(()=>{

               this.notAllowed = false;

           }, this.control)

           this.$emit('click', event, this);

       }

   }

}

</script>


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

按钮点击立马禁用,等响应回来才能继续点击

触发点击的button实例传入fetch配置,代码如下:


doQuery: function (button) {

   this.FesApi.fetch(`generalcard/query`, {

       sub_card_type: this.query.sub_card_type,

       code_type: this.query.code_type,

       title: this.query.title,

       card_id: this.query.card_id,

       page_info: {

           pageSize: this.paginationOption.page_info.pageSize,

           currentPage: this.paginationOption.page_info.currentPage

       }

   }, {

       //看这里,加上下面一行代码就行。。so easy

       button: button

   }).then(rst => {

       // 成功处理

   });

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

在fetch函数内部,设置button的disabled=true,当响应回来时,设置disabled=false代码如下:


const action = function (url, data, option) {

   // 如果传了button

   if (option.button) {

       option.button.currentDisabled = true;

   }

   // 记录日志

   const log = requsetLog.creatLog(url, data);


   return param(url, data, option)

       .then(success, fail)

       .then((response) => {

           requsetLog.changeLogStatus(log, 'success');

           if (option && option.button) {

               option.button.currentDisabled = false;

           }

           return response;

       })

       .catch((error) => {

           requsetLog.changeLogStatus(log, 'fail');

           if (option && option.button) {

               option.button.currentDisabled = false;

           }

           error.message && window.Toast.error(error.message);

           throw error;

       });

};


目录
相关文章
|
5天前
|
自然语言处理 JavaScript 前端开发
三个JavaScript面试题
摘要: - 闭包是JavaScript函数能记住词法作用域,即使在外部执行。示例:计数器函数`createCounter()`返回访问`count`的匿名函数,每次调用计数递增。 - 事件循环处理异步操作,通过检查任务队列执行回调。示例:`setTimeout`异步任务在3秒后添加到队列,待执行,输出顺序为同步任务1、2,然后异步任务1。 - 箭头函数是ES6简洁的函数定义方式,如`greet = name =&gt; `Hello, ${name}!`。它没有自己的`this`,不适用作构造函数。
25 6
|
13天前
|
存储 JavaScript 前端开发
每日一道javascript面试题(九)函数的参数可以和函数体中的变量重名吗
每日一道javascript面试题(九)函数的参数可以和函数体中的变量重名吗
|
13天前
|
存储 JavaScript 前端开发
每日一道javascript面试题(八)你真的知道了解const吗
每日一道javascript面试题(八)你真的知道了解const吗
|
13天前
|
JavaScript 前端开发
每日一道javascript面试题(七)你真的知道箭头函数吗
每日一道javascript面试题(七)你真的知道箭头函数吗
|
13天前
|
JavaScript 前端开发
每日一道javascript面试题(六)有var和无var
每日一道javascript面试题(六)有var和无var
|
JavaScript 前端开发 索引
|
12天前
|
存储 移动开发 JavaScript
学习javascript,前端知识精讲,助力你轻松掌握
学习javascript,前端知识精讲,助力你轻松掌握
|
19天前
|
JavaScript 前端开发 测试技术
学习JavaScript
【4月更文挑战第23天】学习JavaScript
13 1
|
26天前
|
JavaScript 前端开发 应用服务中间件
node.js之第一天学习
node.js之第一天学习
|
2月前
|
运维 JavaScript 前端开发
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!