ES6-9 对象密封4种方式、assign、取值函数的拷贝

本文详细介绍了ES6中四种对象密封的方法,包括Object.preventExtensions、Object.defineProperty、Object.seal以及Object.freeze,并探讨了Object.is的用法、Object.assign的深浅拷贝特性以及如何处理嵌套对象和属性覆盖。此外,还提到了Symbol原始类型和使用Object.defineProperties进行属性拷贝的重要性。
摘要由CSDN通过智能技术生成

一 对象密封

1 Object.preventExtensions 禁止对象拓展,仍可删除

  • 严格模式下报错
const origin = {
    a: 1
}
const fixed = Object.preventExtensions(origin)
console.log(origin === fixed) // true
console.log(Object.isExtensible(origin)) // false 不可拓展
origin.b = 100
console.log(origin) // 不变

2 Object.defineProperty

const obj = {}
obj.b = 1 // 属性描述符全是true
console.log(Object.getOwnPropertyDescriptor(obj, 'b'))
Object.defineProperty(obj, 'c', {
    value: 100 // 属性描述符全是false
})
console.log(Object.getOwnPropertyDescriptor(obj, 'c'))

3 Object.seal 对象密封 禁止拓展+不可删除,仍可修改

  • 严格模式下报错
const origin = {
    a: 1
}
const fixed = Object.seal(origin)
console.log(origin === fixed) // true
console.log(Object.isSealed(origin)) // true 密封的
console.log(Object.isExtensible(origin)) // false 不可拓展
delete origin.a 
console.log(origin) // 不变,不可删除
origin.a = 100
console.log(origin) // 不可删除, 仍可修改

4. Object.freeze - 冻结的 不可增删改

const origin = {
    a: 1
}
const fixed = Object.freeze(origin)
console.log(origin === fixed) // true
console.log(Object.isFrozen(origin)) // true 冻结的
console.log(Object.isSealed(origin)) // true 密封的
console.log(Object.isExtensible(origin)) // false 不可拓展
origin.a = 100
console.log(origin) // 不可修改

二 Object.is

console.log(NaN === NaN) // false
console.log(+0 === -0) // true 
console.log(Object.is(NaN, NaN)) // true 和全等不同的
console.log(Object.is(+0, -0)) // false 和全等不同的
console.log(Object.is({}, {})) // false

三 Object.assign(tar, …sources) 合并对象

const tar = {}
const obj = {a: 1}
const copy = Object.assign(tar, obj)
console.log(copy === tar) // true
// 直接使用tar
  • 属性覆盖:取后写的

  • 当tar是不能转为对象的原始值null/undefined时,报错
    在这里插入图片描述
    在这里插入图片描述

  • source能转成对象,且属性的可枚举性为真,则可以合并得到新的对象
    在这里插入图片描述

  • source为数组时
    在这里插入图片描述

  • Object.assign拷贝的是可枚举属性,继承属性和不可枚举属性不可拷贝
    在这里插入图片描述

const obj = Object.create({ foo: 1 }, {
    bar: {
        value: 2 // 只可读
    },
    baz: {
        value: 3,
        enumerable: true
    }
})
console.log(obj)
console.log(Object.getOwnPropertyDescriptor(obj, 'bar'))
console.log(Object.getOwnPropertyDescriptor(obj, 'foo')) // 拿不到继承属性的属性描述符
const copy = Object.assign({}, obj)
console.log(copy)
console.log(Object.assign(obj, { extra: 100 }))

Object.assign是浅拷贝

  • 在嵌套的对象里要尤其注意
    在这里插入图片描述

嵌套对象,同名属性会被后者替换

console.log(Object.assign([1,2,3],[4,5]))
// {0: 4, 1: 5, 2: 3}

含getter

在这里插入图片描述
在这里插入图片描述

含setter

在这里插入图片描述
在这里插入图片描述

const obj1 = {
    set a(val) {
        this._a = val
    }
}
obj1.a = 100
const obj2 = Object.assign({}, obj1)
console.log(obj2)

扩充原型上的方法、属性

function Person() { }
Object.assign(Person.prototype, {
    name: 'hh',
    eat() { }
})
console.log(Person.prototype)

设置默认项

const DEFAULT = {
    url: {
        host: 'www.baidu.com',
        port: 80
    }
}
function test(opt) {
    opt = Object.assign({}, DEFAULT, opt)
    console.log(opt)
}
test({
    url: { port: 8080 }
})
test()

在这里插入图片描述

四 Symbol 原始类型

  • 可以看成永远不会重复的字符串
const a = Symbol('1')
const b = Symbol('1')
console.log(a) // Symbol(1)
console.log(b) // Symbol(1)
console.log(a === b) // false
console.log(a == b) // false

五Object.defineProperties/getOwnPropertyDescriptors

  • 获取多个描述/定义多个属性
const obj1 = {}
Object.defineProperty(obj1, 'a', {
    value: 'a'
})

Object.defineProperties(obj1, {
    b: {
        value: 'b'
    },
    c: {
        value: 'c'
    },
})
console.log(Object.getOwnPropertyDescriptor(obj1, 'a'))
console.log(Object.getOwnPropertyDescriptor(obj1, 'b'))
console.log(Object.getOwnPropertyDescriptor(obj1, 'c'))
console.log(Object.getOwnPropertyDescriptors(obj1))

在这里插入图片描述

  • 解决Object.assign不能拷贝setter/getter的问题
const source = {
    set foo(val) {
        this.a = val
    }
}
console.log(source)
const tar = {}
Object.defineProperties(tar, Object.getOwnPropertyDescriptors(source))
console.log(tar)
console.log(Object.getOwnPropertyDescriptors(tar))
tar.foo = 100
console.log(tar)

在这里插入图片描述

  • 拷贝
const source = {
    a: 100,
    set foo(val) {
        this.a = val
    }
}
const clone = Object.create(Object.getPrototypeOf(source), Object.getOwnPropertyDescriptors(source))
console.log(clone)
clone.foo = 101
console.log(clone)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值