1,判断一个对象为空的方法
方法一:
将对象转换为字符串,判断是否为'{}',相等则对象为空
let obj = {}
console.log(JSON.stringify(obj) === '{}')
方法二:for in 循环
function emptyObj(obj){
for(let key in obj) {
return false //若不为空,可遍历,返回false
}
return true
}
方法三:
使用Object.keys()获取对象的key的集合,返回一个数组,如果该数组的长度等于0,则该对象为空
console.log(Object.keys(obj).length === 0)
方法四:
使用Object.getOwnPropertyNames()方法获取对象的属性名,存到数组中,判断数组长度
console.log(Objec.getOwnPropertyNames(obj).length === 0)
2,数组forEach和map方法的区别
相同点:
1) 都可以遍历数组
2) 每次执行都支持三个参数,item 数组的每一项, index 数组的索引,arr 当前数组
3)匿名函数的this都指向window
4)只能遍历数组
不同点:
1)map有返回值,forEach没有返回值,也不能return
2)map返回新的数组,map不会对空数组进行检测
3,判断数组类型的方法
方法一:isArray(推荐)
let arr = [1,2,3,4]
console.log(Array.isArray(arr)
方法二:instanceof
console.log(arr instanceof Array) // true
方法三:constructor
cconsole.log(arr.constructor === Array) // true
方法四:Object.prototype.toString.call()
console.log(Objec.prototype.toString.call(arr) === '[Object Array]')
方法五:isPrototypeof()
console.log(Array.isPrototypeof(arr))
4,构造函数
构造函数:是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,总于new运算符
yi起使用在创建对象的语句中。
5,new 一个对象的过程
1,创建一个新对象
2,将对象的原型指向构造函数的原型
3,将空对象作为构造函数的上下文(改变this指向)
4,对构造函数有返回值的处理(返回基本数据类型的值则忽略,返回引用数据类型的时,返回该数据)
6,promise是同步还是异步,promise的then()方法是同步还是异步,promise有几个状态
promise本身是同步,它的then方法是异步的
promise有三个状态,初始状态pending,成功状态 fulfilled, 失败状态rejected
7,实现异步的方法
方法一:async函数 (async await 将异步转换为同步)
方法二:promise的then方法,解决回掉地狱的问题,缺点是一旦执行不能停止,报错需要回掉函数捕获
方法三:事件监听
方法四:回掉函数,现在比较少用,容易造成回掉地狱
8,防抖和节流
防抖和节流都是为了解决事件频繁出发的问题
一,防抖:当持续触发事件时,在一定的时间内没有在触发事件,事件才会处理,如果在设定的时间内
又触发了事件,则重新开启定时器,执行最后一次触发事件(事件只执行一次)
应用场景:scroll事件滚动,浏览器窗口的缩放resize事件,搜索框输入查询,按钮的提交事件等
代码
function debounce(fn, delay = 1000) {
let time = null;
return function() {
// 获取当前this
let _this = this
// 判断time是否已经存在,如果存在直接清楚
if(time) {
clearTimeout(time)
}
time = setTimeout(() => {
// 使用fn中的this,执行当前调用者,并传入参数
fn.apply(_this, arguments)
}, delay)
}
}
function test() {
console.log('测试防抖')
}
btn.addEventListener('click', debounce(test, 1000))
二,节流:在持续触发事件时,在一定时间内只调用一次函数,如果在规定时间内,再次触发该函数,则直接忽略
,主要目的就是减少一段时间的触发频率
应用场景:DOM元素拖拽功能实现,计算鼠标移动距离等
代码
function throttle(fn, delay = 1000) {
let time = null
return function(){
let _this = this
// 如果已经存在定时器,则不做处理
if (!time) {
time = setTimeout(() => {
fn.apply(that, argument)
// 完结时,将time改为null
time = null
}, delay)
}
}
}
9,闭包是什么
闭包:在一个函数里面再定义一个函数。内部函数可以调用外部函数的参数
闭包的用途:1,可以读取函数内部的变量 2,让变量始终保存到内存中
注意:闭包会使得函数中的变量都被保存到内存中,内存消耗很大,所以不能滥用闭包。(在IE中可能会导致内存泄露)
10,箭头函数与普通函数的区别,可以new一个箭头函数吗
1,写法不一样
// 普通函数
function fun(){
console.log('普通函数')
}
//箭头函数
let fun = () => {
console.log('箭头函数')
}
2,两者的this指向不同
普通函数的this:谁调用该函数就指向谁
箭头函数的this:书写代码时候的上下文环境对象的this,如果没有上下文环境,
就指向最外层对象window
3,箭头函数的arguments指向其父级函数作用于的arguments4,箭头函数没有new.target
new.target是用来检测函数是否被当作构造函数使用,它会返回一个指向构造函数的引用
不能new一个箭头函数,因为箭头函数不能作为构造函数使用