一、判断对象是否为空

// 第一种方法: 将当前的对象通过 JSON.stringify() 方法转对象字符串:
let obj = {}
let newObj = JSON.stringify(obj)
console.log(newObj === '{}') // true

// 第二种方法: 通过 for in 循环方法判断当前对象中是否有属性key
checkObject(obj) {
  for (let key in obj) {
    return false;
  }
  return true;
}
// 调用 checkObject() 方法
let obj1 = {}
console.log(checkObject(obj1)) // true

// 第三种方法: 使用 Object.getOwnPropertyNames() 判断,
// 该方法返回的是由对象属性组成的数组,然后判断数组的长度即可
let obj = {};
let keyArr = Object.getOwnPropertyNames(obj)
console.log(keyArr.length) // 0

// 第四种方法: 使用 Object.keys() 判断,
// 该方法获取给定对象可枚举属性的字符串数组,然后判断数组的长度即可
let obj = {};
let keyArr = Object.keys(obj)
console.log(keyArr.length) // 0

二、vue组件通信都有哪些方法

// 第一种:使用 props / $emit 
// 父组件向子组件传值使用props,子组件向父组件传值使用this.$emit


// 第二种:使用回调函数(callback)
// 在父组件中将submitChils传给子组件
<ChlisCom :msg="msg" :submitChils="submitChil"></ChlisCom>
// 在子组件中先声明,再使用 
props: ["submitChils"],
<button @click="submitChils">向父组件提交数据</button>


// 第三种:使用 $parent / $children
// 主要使用的是Vue实例上的parent和chilren方法,
// 获取父组件data中的数据时使用computed计算属性:
messageNUM() {
    return this.$parent.msg
}
// 父组件向子组件传值使用 this.$children[0].number = 50


// 第四种:使用 provide / inject
// 在父组件中定义:
provide:{
   mack:'今天星期四吧'
},
// 在子组件中接收:
inject:['mack']


// 第五种:使用 $attrs / $listeners 该方法是父组件可以传给子组件也可以传给孙组件
// 父组件将值传给子组件
 <ChlisCom :name="name" :age="age" @grandsonCom="grandsonCom"></ChlisCom>
// 子组件通过$attrs把值传给孙组件
<GrandsonCom v-bind="$attrs"></GrandsonCom>
// 孙组件拿到值使用$attrs.name将值显示在界面上
<p>姓名:{{ $attrs.name }}</p>

// 父组件将方法grandsonCom传给子组件时,子组件使用$listeners.grandsonCom添加在监听事件上
<button @click="$listeners.grandsonCom">修改父组件传给孙组件的值</button>


//第六中:使用ref
//在子组件上定义一个res
<ChlisCom ref="chlis"></ChlisCom>
然后在父组件的methods中函数调用
this.$refs.chlis.vp() // 触发子组件中的方法
this.cop = this.$refs.chlis.cop // 获取子组件data中的值


//第七种:vuex

三、数组都有哪些方法?

join() // join(separator): 将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符,该方法只接收一个参数:即分隔符。
push() // 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。 
pop() // 数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
shift() // 删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 
unshift() // 将参数添加到原数组开头,并返回数组的长度
sort() // 按升序排列数组项——即最小的值位于最前面,最大的值排在最后面
reverse() // 反转数组项的顺序
concat() // 合并数组,将参数添加到原数组中
slice() // 返回从原数组中指定开始下标到结束下标之间的项组成的新数组
splice() // 很强大的数组方法,它有很多种用法,可以实现删除、插入和替换
indexOf() // 接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找
lastIndexOf() // 接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。


forEach() // 对数组的每一项运行给定函数,该方法没有返回值
some() // 对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true
filte() // 对数组的每一项运行给定函数,返回该函数会返回true的项组成的数组。
map() // 对数组的每一项运行给定函数,返回每次函数调用结果所组成的数组

四、深拷贝的几种实现方式

// 方法一: 使用递归的方式实现数组、对象的深拷贝
export function deepClone1 (obj) {
  const objClone = Array.isArray(obj) ? [] : {}
  if (obj && typeof obj === 'object') {
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        if (obj[key] && typeof obj[key] === 'object') {
          objClone[key] = deepClone1(obj[key])
        } else {
          objClone[key] = obj[key]
        }
      }
    }
  }
  return objClone
}

// 方法二: 通过json对象实现深拷贝
// 通过js的内置对象JSON来进行数组对象的深拷贝,缺点是:无法实现对对象中方法的深拷贝
export function deepClone2 (obj) {
  const newObj = JSON.stringify(obj)
  const objClone = JSON.parse(newObj)
  return objClone
}

// 方法三:通过jquery的extend方法实现深拷贝
export function deepClone3 (array) {
  const newArray = $.extend(true, [], array)
  return newArray
}

// 方法四:Object.assign()拷贝
// 当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。

// 方法五:lodash函数库实现深拷贝
// lodash.cloneDeep()```