对象方法全知道

56 阅读2分钟

对象属性

const object1 = {
  a: 'somestring',
  b: 42,
  c: false,
}

有两种方法取到对象属性值,第一种是:

object1.a

或者是

object1['a']

如果是[]形式,会自动把它当做一个变量来解释。或者说,当成一个js表达式。

对象解构赋值

对象重命名

const obj = {
    iProjectId: 1,
    sStatus: 'done',
}
const { iProjectId: id, sStatus: status } = obj
console.log(id, status)   // 1 'done'

提取部分对象

const obj = {
    iProjectId: 1,
    sStatus: 'done',
    sValue: 'value'
}
const { iProjectId: id, ...extra } = obj
console.log(extra)   // {sStatus: 'done', sValue: 'value'}

对象重命名

Object.keys() 和 Object.prototype.hasOwnProperty()

遍历对象属性的时候,我们可以用for..in方法,这种方式有种缺点,就是会遍历原型链上的方法,因此,我们可以用Object.keys遍历当前可枚举属性:

const object1 = {
  a: 'somestring',
  b: 42,
  c: false,
};
Object.prototype.d = '1'


for(let key in object1) {
    console.log(key)
}
// Expected output: a b c d

for(let key of Object.keys(object1)) {
    console.log(key)
}
// Expected output: a b c

也可以用hasOwnProperty的方式,判断是否是自有属性:

for(let key in object1) {
  if(object1.hasOwnProperty(key)){
   console.log(key) 
  }  
}
// Expected output: a b c

这样运行结果也是a b c

应用

在我们进行深拷贝的过程中,如果原型链上有可以迭代的属性,我们不进行判别属性是否是原型链上就进行拷贝,会产生后果: 例如,我们让原本的对象

let obj = {
    name: 'Lisa',
    age: undefined,
    list: ['a', 'b', 'c', 'd' ],
    date: new Date('2023/05/01') 
}
Object.prototype.xiao = 'xiao'

然后我们进行深拷贝:

const deepClone = function(obj) {
    if (obj === null || typeof(obj) !== 'object' || obj instanceof Date) {
        return obj
    }

    const newObj = Array.isArray(obj) ?  [] : {}

    for (const key in obj) {
        newObj[key] = deepClone(obj[key])
    }

    return newObj

}

拷贝结果为如下,将原型链上的属性也错误拷贝了

image.png

因此,将深拷贝函数修改为:

const deepClone = function(obj) {
    if (obj === null || typeof(obj) !== 'object' || obj instanceof Date) {
        return obj
    }

    const newObj = Array.isArray(obj) ?  [] : {}

    for (const key of Object.keys(obj)) {
        newObj[key] = deepClone(obj[key])
    }

    return newObj

}

或者增加判断条件即可。

判断是否是对象

Object.prototype.toString(str) === [object String]