正文
Object.prototype.toString()
- 返回的是`[object Object]`表示数据 类型的字符串
- 可以利用这一点来确定数据的具体类型
- 和
[].toString()
以及Number.prototype.toString()
都不一样,数组和字符串等类型数据都重写了toString()
方法。
javascript">function type(val) {
return {}.toString.call(val)
}
console.log(type([])); //[object Array]
console.log(type(null)); //[object Null]
console.log(type(undefined)); //[object Undefined]
console.log(type('')); //[object String]
console.log(type(new Set())); //[object Set]
console.log(type(false)); //[object Boolean]
注意: 拷贝之后,两个对象中的函数是一个函数,也就是说两个函数名都指向一个函数对象
- 第一种写法
javascript">function deepClone(sourceObj, resultObj) {
resultObj = resultObj ? resultObj : {}
for (let key in sourceObj) {
//这是属性得是自己有的,不是继承过来的
if (sourceObj.hasOwnProperty(key)) {
//得是个引用类型的数据,才去递归啊,也不能是空
if (typeof sourceObj[key] === 'object' && sourceObj[key]) {
if (Object.prototype.toString.call(sourceObj[key]) === '[object Object]') {
//是对象
resultObj[key] = {}
} else {
//是数组
resultObj[key] = []
}
//递归
deepClone(sourceObj[key], resultObj[key])
} else {
//简单数据类型或者是函数就直接赋值了
resultObj[key] = sourceObj[key]
}
}
}
return resultObj
}
- 第二种写法
javascript">function deepClone(target) {
//传入的数据类型不是对象,或在递归对象属性时,如果属性不是对象,则直接返回,不需要深拷贝
if (typeof target !== 'object') {
return target
}
let result
if ({}.toString.call(target) === '[object Object]') {
//是对象
result = {}
} else {
//是数组
result = []
}
for (let key in target) {
//只处理自己的属性,不处理继承过来的共有的属性
if (target.hasOwnProperty(key)) {
result[key] = deepClone(target[key])
}
}
return result
}
- 这里有个小插曲,
Function
类型我知道是引用类型数据,于是想验证一下函数是否也深拷贝了- 我同理了
Object
引用类型的特点,就是浅拷贝之后,改变一个对象的属性,另一个对象也会改变,且两个对象会相等。如下
- 我同理了
javascript">const obj1 = {
name: 'zed'
}
const obj2 = obj1
console.log(obj1 === obj2) //true
obj2.name = '111'
console.log(obj1) //111
console.log(obj2) //111
- 但是我很惊讶的发现,结果是两个函数互不影响,也就是意味着函数不是引用类型?(是!!)。这直接让我怀疑人生,甚至去查函数是否是引用类型。
- 不过当我细心观察代码时,发现其实这不过就是一场闹剧:我在改变
fn1
函数时,改变的不是它所指向的函数对象,而是改变了fn1
的指向,直接让它指向了一个新的函数对象。这当然与对象的修改不同,是我想的简单了。 - 结论就是:函数是引用类型!
javascript">let fn1 = () => {
console.log(111)
}
let fn2 = fn1
console.log(fn1 === fn2) //true
fn1 = () => {
console.log(222)
}
fn1() //222
fn2() //111
结语
如果对你有帮助的话,请点一个赞吧