一.对象密封的4种方式
(1).访问对象下的伪元素函数名
const obj = {
get foo(){
},
set foo(x){
}
}
log(obj.foo.name)//这样会报错因为打印Obj.foo == un
var descriptor = Object.getOwnPropertyDescriptor(obj,'foo');
log(descriptor.get.name);//打印get foo set访问也同理
(2).preventExtensions
var obj = {a: 2};
log(Object.preventExtensions(obj));//{a: 2};
obj.b = 3;
log(obj);//{a:2}
log(Object.isExtensible(obj)); //false 不可拓展
var obj = {a: 2};
Object.preventExtensions(obj);
Object.defineProperty(obj,'b',{
value: 6
})
(3).defineProperty()特性
通过defindproperty配置描述符全部为false,通过点配置全部为true
(4).seal/isSealed
var obj = {a : 2};
Object.seal(obj);
log(Object.isSealed(obj))//true 被密封 底层把所有的configurable改为false
(5).freeze/isFrozen
Object.freeze(obj);
log(Object.isFrozen(obj));//为true则代表已经冻结
function myFreeze(obj){
Object.freeze(obj);
for(var key in obj){
if(typeof(obj[key]) === 'object' && obj[key] !== null){
myFreeze(obj[key])
}
}
}
(6).is
log(+0 === -0);//true
log(NaN === NaN);//false
log(Object.is(NaN,NaN))//true
log(Object.is(+0,-0))//false
二.assign
(1).基础
let obj = {a: 1};
let tar = {};
let copy = Object.assign(tar,obj);
log(copy);//{a: 1}
log(copy === tar) //true
log(copy === obj) //false
证明assign返回的对象就是原对象
(2).合并和覆盖的情况
合并
const tar = {a: 1};
const tar2 = {b: 2};
const tar3 = {c: 3};
Object.assign(tar,tar2,tar3)
log(tar);//{a:1,b:2,c:3}
覆盖
const tar = {a:1,b:1};
const tar2 = {b:2,c:2};
const tar3 = {c:3}
Object.assign(tar, tar2, tar3);
console.log(tar);//{a:1,b:2,c:3}
(3).第一个参数为原始值
Object.assign(undefined,{a:1});
var test = Object.assign(1,{a:1});
console.log(test);//Number{1,a:1}
(4).第二个参数为原始值
var test = Object.assign({a:1},'123');
log(test);
0: "1"
1: "2"
2: "3"
a: 1
如果第二个参数为boolean和number类型的都输出{}
var test = Object.assign([1,2,3,4],123);
console.log(test);[1,2,3,4]
var test = Object.assign([1,2,3,4],'321');
console.log(test);
["3", "2", "1", 4]
三.取值函数的拷贝
(1).基础
var obj = Object.create({foo:1},{
bar:{
value:2
},
baz:{
value:3,
enumberable:true
}
})
log(obj)//
{
baz:3
bar:2
__proto__:
foo:1
}
//原型上的属性不管可不可以枚举的都不能拷贝
var copy = Object.assign({},obj);
log(copy);//{baz:3}
(2).symbol
var a = symbol();
var b = symbol();
log(a === b);//打印false
var a = symbol('a');
var b = symbol('a')
log(a == b)//打印false
var test = Object.assign({a:'b'},{[Symbol('c')]:'d'});
log(test);
//{a:"b",Symbol(c):"d"}
(3).拷贝
const obj1 = {a:{b:1}};
const obj2 = Object.assign({},obj1);
obj1.a.b = 2;
log(obj2);//{a:{b:2}}
证明是直接替换的没有单个深入替换
const target = {a:{b:'c',d:'e'}};
const sourse = {a:{b:'hello'}};
Object.assign(target, sourse);
log(target);//{a:{b:hello}}
数组替换
var a = Object.assign([1, 2, 3],[4,5]);
log(a);//输出[4,5,3]
const sourse = {
get foo(){
return 1;
}
}
const target = {};
Object.assign(target,sourse);
log(target); //{foo:1}
这样就不行
const sourse = {
set foo(value){
log(value);
}
}
const tar = {};
Object.assign(tar,sourse);
log(tar);//{foo:un}
var age = 1;
function Person(){}
Object.assign(Person.prototype,{
eat(){
},
age
})
log(Person.prototype);
//{age:1,eat:eat()}
const DEFAULT = {
url: {
host: 'www.baidu.com',
port: 7070
}
}
function test(option){
option = Object.assign({},DEFAULT,option);
log(option)
}
不传参
test();//{url:{host:'www.baidu.com',port:7070}}
传参
test({url:{port:8080}})//{url:{host:'www.baidu.com',port:8080}}
defineProperties()/getOwnPropertyDescriptors()
var obj = {}
Object.defineProperties(obj,{
a:{
value: true,
writable: true
},
b:{
value: 'hello',
writable: false
}
})
log(Object.getOwnPropertyDescriptors(obj));
//{
a:
configurable: false
enumerable: false
value: true
writable:true
}
//{
b:
configurable: false
enumerable: false
value: 'hello'
writable:true
}
getOwnPropertyDescriptors/defineProperties
问题的抛出
const sourse = {
set foo(value){
log(value);
}
}
const tar = {};
Object.assign(tar,sourse);
log(tar);//{foo:un}
这样解决
Object.defineProperties(tar, Object.getOwnPropertyDescriptors(sourse));
log(Object.getOwnPropertyDescriptor(tar,'foo'));
//{
configurable: true
enumerable: true
get:undefined
value: f foo(value)
writable:true
}
var obj = {a:1, b:2, c:3}
const clone = Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj))
log(clone) {a:1,b:2,c:3}
//优化写法
const clone = (obj) => Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj))
1.const obj = Object.create(prot);
2.const obj = Object.assign(Object.create(prot),{
3.const obj = Object.create(prot,Object.getOwnPropertyDescriptors({