对象密封的四种方式
preventExtensions
禁止对象的扩展 isExtensible false 不可扩展 true 可扩展
var obj = { a: 2 };
Object.preventExtensions(obj);
console.log(Object.isExtensible(obj));
seal
对象的密封 isSealed true 密封的 false 不密封的
var obj = { a: 2 };
Object.seal(obj);
console.log(Object.isSealed(obj));
freeze
冻住的 isFrozen true 被冻住的 false 没有被冻住的
var obj = { a: 2 };
Object.freeze(obj);
console.log(Object.isFrozen(obj));
封装myFreeze
function myFreeze(obj) {
Object.freeze(obj);
for (var key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
myFreeze(obj[key]);
}
}
}
Object.is
对于普通情况下
console.log(NaN === NaN);
console.log(+0 === -0);
而在使用Object.is
console.log(Object.is(NaN, NaN));
console.log(Object.is(+0, -0));
除了这两种情况其他的使用下是一样的
console.log({} === {});
console.log(Object.is({}, {}));
Object.assign
Object.assign实现对象的浅拷贝 Object.assign(tar,…sources)
let obj = { a: 1 };
let tar = {};
let copy = Object.assign(tar, obj);
console.log(copy);
我们可以看到下面的情况
let obj = { a: 1 };
let tar = {};
let copy = Object.assign(tar, obj);
console.log(copy);
console.log(copy === obj);
console.log(copy === tar);
所以tar就是当前的拷贝结果
后面的属性会覆盖前面的属性
const tar = { a: 1, b: 1 };
const tar2 = { b: 2, c: 2 };
const tar3 = { c: 3 };
Object.assign(tar, tar2, tar3);
console.log(tar);
对于tar为非对象的情况下 会进行隐式类型转换
const test = Object.assign(1, { a: 2 });
console.log(test);
const test = Object.assign(false, { a: 2 });
console.log(test);
const test = Object.assign('abc', { a: 2 });
console.log(test);
对于非对象进行合并 会进行隐式类型转换 转换后可枚举的才可以合并
const test1 = 'abc';
const obj = Object.assign({}, test1);
console.log(new String(test1));
console.log(obj);
const test2 = false;
const obj = Object.assign({}, test2);
console.log(new Boolean(test2));
console.log(obj);
const test3 = 10;
const obj = Object.assign({}, test3);
console.log(new Number(test3));
console.log(obj);
继承属性 和不可枚举属性 不能拷贝
var obj = Object.create(
{ foo: 1 },
{
var: {
value: 2,
},
baz: {
value: 3,
enumerable: true,
},
}
);
console.log(obj);
var copy = Object.assign({}, obj);
console.log(copy);
Symbol类型的也可以拷贝
var test = Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' });
console.log(test);
浅拷贝
const obj1 = { a: { b: 1 } };
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
console.log(obj2);
同名属性的替换 整体替换
const target = { a: { b: 'c', d: 'e' } };
const sources = { a: { b: 'hello' } };
Object.assign(target, sources);
console.log(target);
数组的替换从索引为0开始替换
var a = Object.assign([1, 2, 3], [4, 5]);
console.log(a);
没有拷贝整个函数
const source = {
get foo() {
return 1;
},
};
const target = {};
Object.assign(target, source);
console.log(target);
在原型上扩充属性与方法
function Person() {}
var age = 1;
Object.assign(Person.prototype, {
eat() {},
age,
});
console.log(Person.prototype);
可以通过Object.assign定义默认值 如果当我们不传递第三个参数时 第二项是默认值 传入第三项就会抵消第二项的值
const DEFAULT = {
url: {
host: 'www.baidu.com',
port: 7070,
},
};
function test(option) {
option = Object.assign({}, DEFAULT, option);
console.log(option);
}
test({ url: { port: 8080 } });
Object.assign是无法合并set get 方法的
const source = {
set foo(value) {
console.log(value);
},
};
const str = {};
Object.assign(str, source);
console.log(str);
我们可以使用defineProperties并且 使用Object.getOwnPropertyDescriptors获取get与set方法 就可以解决set赋值函数不能拷贝的问题
const source = {
set foo(value) {
console.log(value);
},
};
const str = {};
Object.defineProperties(str, Object.getOwnPropertyDescriptors(source));
console.log(str);
Object.create也可以用来克隆 使用Object.getPropertOf获取对象的原型
var obj = { a: 1, b: 2, c: 3 };
const clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
console.log(clone);
|