处理对象用过哪些方法?
Object.assign()通过复制一个或多个对象来创建一个新的对象。
Object.create()使用指定的原型对象和属性创建一个新对象。
Object.defineProperty()给对象添加一个属性并指定该属性的配置。
Object.defineProperties()给对象添加多个属性并分别指定它们的配置。
Object.entries()返回给定对象自身可枚举属性的[key, value]数组。
Object.freeze()冻结对象:其他代码不能删除或更改任何属性。
Object.is()比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)。
Object.isExtensible()判断对象是否可扩展。
Object.isFrozen()判断对象是否已经冻结。
Object.isSealed()判断对象是否已经密封。
Object.keys()返回一个包含所有给定对象自身可枚举属性名称的数组。
Object.values()返回给定对象自身可枚举值的数组。
Math对象常用的方法?
--floor(x)对数进行下舍入
--random()返回 0 ~ 1 之间的随机数
-- ceil(x)对数进行上舍入
js的数据类型有哪些?
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型:对象(Object)【数组(Array)、函数(Function)】。
substr与substring的区别?
substr( ) 截取字符串 。(返回从start位置开始length长度的子串)
substring( )返回字符串的一个子串 (返回从start位置开始到end位置的子串(不包含end))
数组的map,filter,forEach的区别?
共同点:
都有三个参数,第一个是数组中每个元素的值,第二个是下标,第三个是数组本身。
不同点:
map:他有return,可以返回更改后新的数组。
forEach:他的return返回undefined,他一般在函数中直接进行操作,直接操作,会改变原数组。
filter:他也有return,可以按照指定的条件来过滤数组,也会返回一个新的顾虑后的数组。
闭包?
有权访问函数内,私有变量的函数,也因为他是一个私有变量的函数,所以垃圾回收机制无法回收,就造成了内存泄漏。
闭包的适用场景?
1.选项卡和焦点轮播图
2.模块化开发 每一个组件就是一个闭包函数
什么是内存泄漏?
内存泄漏指因为疏忽或错误造成程序未能释放已经不在使用的内存的情况。
内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,而造成内存的浪费。
如何解决内存泄漏?
(1)良好的编码习惯,尽量在设计内存的程序段,检测出内存泄漏。
(2)使用了内存分配的函数或变量,使用完毕后,及时清除
什么是垃圾回收机制?
会定期对那些我们不再使用的变量、对象所占用的内存进行释放
Javascript 的垃圾回收机制:变量生命周期结束,内存会被回收
垃圾回收机制的算法有两点:
1.标记清除:标记清除和引用计数
2.引用计数:统计引用类型变量声明后被引用的次数,当次数为 0 时,该变量将被回收
全局变量:生命周期会一直持续,直到页面卸载
局部变量:函数调用结束,局部变量也不再被使用,它们所占用的空间也就被释放
闭包:由于闭包的原因,局部变量依然在被使用,所以也就不能够被回收
如何解决: 手动清除
说下原型链?
由实例对象的__proto__串起来到object.prototype.__proto__为空的链,就叫原型链
当js引擎查找对象的属性时,如果当前对象没有 就会去原型链上去找
js事件流?
1.冒泡型事件流:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。
2.捕获型事件流:事件开始时由最不具体的元素接收,然后逐级向下传播到较为具体的节点。
深拷贝和浅拷贝?
浅拷贝:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。
深拷贝:在内存中开一块新的内存地址,用于存放复制的新对象。
深拷贝方法:
1.通过递归与for..in
var obj = { a: 1, arr: [1, 2], nation: '中国', birthplaces: ['北京', '上海', '广州'], fn1: function() {alert('拷贝我呀')} }; var obj2 = { name: '杨' }; obj2 = deepCopy(obj, obj2); console.log(obj2); //深复制,要想达到深复制就需要用递归 function deepCopy(a, b) { // 如果b传值了,就是b,如果没有就是空对象 var b = b || {}; // 遍历a的健名为i for (var i in a) { // 如果a对象当前的健名类型是object if (typeof a[i] === 'object') { // 如果a对象当前的元素的构造器是Array if (a[i].constructor === Array) { //那么b对象里的i属性就是个数组 b[i] = []; } else { //否则b对象里的i属性就是个对象 b[i] = {}; } // 如果符合上面的条件之一,那我就在调用自己,把当前的对象或者数组和 // 跟他对应新创建的对象或数组一起传进去,在判断是不是,直到判断不是以后 deepCopy(a[i], b[i]); } else { // 就把a对象的值,在赋值给b对象 b[i] = a[i]; } } // 通过这样递归,就可以把原对象中的属性逐个复制出来。 // 最后把复制好的breturn出来就可以了 return b; }
递归的另一种写法:
function deepClone(obj) { var newObj = obj instanceof Array ? [] : {}; if (typeof obj !== 'object') { return obj; } else { for (var i in obj) { newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]; } } return newObj; } var a = [1, 2, 4, 6, "a", "12", [1, 2]]; var b = deepClone(a); a[3] = 7; console.log(a); console.log(b);
2.通过
创建一个方法,传入一个obj对象,借用JSON.stringify和parse,stringify把传入的对象转成json字符串,然后再把json字符串通过parse,转换成原生js对象,在返回一个新的对象(函数不行,有缺陷)
var a = { a: 1, arr: [1, 2], nation: '中国', birthplaces: ['北京', '上海', '广州'] } var b = JSON.parse(JSON.stringify(a)); console.log(a); console.log(b);
3.通过对象合并方法Object.assign,前面加个空对象,来实现深拷贝
var a = { a: 1, arr: [1, 2], nation: '中国', birthplaces: [{name: '北京'}, '上海', '广州'], fn1: function() {console.log('我被拷贝了')} } var b = Object.assign({}, a); console.log(b);
DOM操纵 增删改查?
1.创建节点
document.createEelement 创建元素节点
document.createTextNode 创建文本节点
doucment.createAttribute 属性节点
2.添加节点
appenChild(node)
--添加节点到当前节点内部的后面(新创建的节点)
--移动节点到当前节点内部的后面(已有节点)
insertBefore(要添加或移动的节点,参考节点)
--添加节点到当前节点内部的前面(新创建的节点)
--移动节点到当前节点内部的前面(已有节点)
3.删除节点
remove()删除当前节点
removeChild(node)删除节点
4.复制节点
cloneNode(true)深拷贝
cloneNode(false)浅拷贝
5.替换节点
repalceChild(新节点,被替换的节点)
如何做防止重复提交?
1.react中通过redux-saga的附件effects里的takeList来进行阻止重复提交
2.防抖和节流
什么是防抖?
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
let input = document.getElementById('user_input'); // 存储timeout的id let timeID // 抬起事件 input.onkeyup = () => { // 点完后,如果有定时器正在执行,那么就去除 if (timeID) { clearTimeout(timeID) } // console.log('我是id', timeID) // 只执行,0.3秒后获取输入的值,在发送请求 timeID = setTimeout(() => { // 1.获取用户输入 let { value } = input // 2.模拟发送ajax请求联系服务器 sendAjax(value) }, 300) } function sendAjax(data) { console.log('点击的数据', data) }
什么是节流?
设定一个特定的事件,让函数在特定时间内只执行一次,不会频繁触发。
// 一个标识 let isCanlog = true; // 鼠标滚轮事件 document.onscroll = () => { // 如果标识为true就打印 if (isCanlog) { console.log(1); // 打印完就改成false isCanlog = false; // 一面以后在变成true setTimeout(()=>{ isCanlog = true }, 1000) } }