封装对象
-
阻止对象扩展
Object.preventExtensions()
,与之对应的一个方法Object.isExtensible()
,检测传入的对象是否可扩展,返回一个布尔值,true
可扩展,false
不可扩展。let obj = { a: 1 } Object.preventExtensions(obj); // 返回值为传入的obj本身 obj.b = 2; console.log(obj); // -> {a: 1} Object.defineProperty(obj, 'c', { // -> 直接报错 value: 3 }) console.log(Object.isExtensible(obj)); // -> false
-
密封对象
Object.seal()
,内部通过调用Object.preventExtensions()
,还有一个循环操作,将遍历到的属性的configurable
设置为false
。Object.isSealed()
,检测对象是否密封,true
为密封,false
不密封的。let obj = { a: 1, b: 2 } Object.seal(obj); // 不可配置,不可删除 但是可修改 obj.c = 3; console.log(obj); // -> {a: 1, b: 2} delete obj.a; console.log(obj); // -> {a: 1, b: 2} obj.a = 3; console.log(obj); // -> {a: 3, b: 2} console.log(Object.isSealed(obj)); // -> true
-
冻结对象,
Object.freeze()
,不可写、不可扩展、不可删除。Object.isFrozen()
,检测对象是否冻结,true
冻结,false
没冻结。let obj = { a: 1, b: 2, c: { name: 'foo' } } Object.freeze(obj); Object.isFrozen(obj); // -> true // 浅拷贝的冻结 obj.c.name = 'bar'; console.log(obj); // -> {a: 1, b: 2, c: {name: 'bar'}} // 封装深拷贝冻结 function deepFreeze (obj) { Object.freeze(obj); for(let key in obj){ if(typeof(obj[key]) === 'object' && obj[key] !== null){ deepFreeze(obj[key]); } } }
is
-
Object.is()
与===
内部都是调用sameValue算法,但是有一下两点不同。console.log(NaN === NaN); // -> false console.log(+0 === -0); // -> ture console.log(Object.is(NaN, NaN)); // -> true console.log(Object.is(+0, -0)); // -> false
合并对象
-
Object.assign(tar, ...sources)
,tar为目标对象,sources原对象可以有多个,返回值为目标对象。let o = { name: 'foo' } let t = {}; let copy = Object.assign(t, o); console.log(copy === t); // -> true 说明返回值就是第一个参数目标对象 console.log(t); // -> {name: "foo"}
-
合并/拷贝时,如果出现同名属性,后面的会覆盖前面的。
let tar = { a: 1, b: 1, } let s1 = { b: 2, c: 2 } let s2 = { c: 3 } Object.assign(tar, s1, s2); console.log(tar); // -> {a: 1, b: 2, c: 3}
-
当第一个参数不是对象,会报错。特殊的会调用其对应的包装类的方式,转换为对象。当第二个参数不是对象时,默认不做处理,返回第一个目标对象;可以转为对象的,如果转换为对象的属性可枚举,则可以合并,否则不做处理。
Object.assign(null, {a: 1}); // -> TypeError Object.assign(undefined, {a: 1}); // -> TypeError Object.assign(1, {a: 1}); // -> Number {1, a: 1} Object.assign('1', {a: 1}); // -> String {"1", a: 1} Object.assign(true, {a: 1}); // -> Boolean {true, a: 1} // -------------------------------------------------- Object.assign({a: 1}, undefined); // -> {a: 1} Object.assign({a: 1}, null); // -> {a: 1} Object.assign({a: 1}, 1); // -> {a: 1} Object.assign({a: 1}, '33'); // -> {0: "3", 1: "3", a: 1} Object.assign({a: 1}, true); // -> {a: 1}
-
用于拷贝时, 继承属性和不可枚举属性不能拷贝且属于浅拷贝。
// Object.create() 创建一个对象,第一个参数为这个对象指定原型,第二个参数是一个对象 用于配置对象属性 let obj = Object.create({a: 1}, { b: { value: 2 }, c: { value: 3, enumerable: true } }) console.log(obj); // -> {c: 3, b: 2} let copy = Object.assign({}, obj); console.log(copy); // -> {c: 3}
-
数组也是特殊的对象,合并时有一个坑。
let res = Object.assign([1, 2, 3], [4, 5]); // 根据数组成员对应的下标合并, 1, 2 和 4, 5 的下标相同 所以发生了替换 console.log(res); // -> [4, 5, 3]
属性描述符s
-
上一章介绍了单个属性描述符和配置单个属性,
defineProperties()
和getOwnPropertyDescriptors()
,分别为配置多个属性和获取所有属性描述。let obj = {}; Object.defineProperties(obj, { a: { value: 1, writable: true }, b: { value: 2, writable: false } }) console.log(obj); Object.getOwnPropertyDescriptors(obj); // 可以完美解决 assign 不能拷贝 取值函数和存值函数的问题 let source = { get foo () { // ... }, set foo (val) { // ... } } let tar = {}; Object.assign(tar, source); Object.defineProperties(tar, Object.getOwnPropertyDescriptors(source));
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!