获取属性名称
const obj = {
get foo() {},
// set 最少要有一个参数
set foo(x) {},
};
console.log(obj.foo);
var Descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
console.log(Descriptor.get.name);
console.log(Descriptor.set.name);
阻止对象拓展
Object.preventExtensions
方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
var obj = {
a: 2,
};
// 使用preventExtensions封闭函数
var test = Object.preventExtensions(obj);
obj.b = 3;
// false 该对象不可拓展
console.log(Object.isExtensible(obj));
console.log(test);
使用Object.defineProperty
添加属性,不可以添加
var obj = {
a: 2,
};
// 使用preventExtensions封闭函数
var test = Object.preventExtensions(obj);
// 使用defineProperty添加属性,报错
Object.defineProperty(obj, 'b', {
value: 6,
});
两种增加属性方式的对比
var obj = {
a: 2,
};
// 通过增加的方式定义,b的属性描述符都是true
// obj.b = 3 ;
// 通过 defineProperty 方法增加b属性,属性描述符都是false
Object.defineProperty(obj, 'b', {
value: 6,
});
console.log(Object.getOwnPropertyDescriptor(obj, 'b'));
Object.seal 和 Object.isSealed
封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
var obj = {
a: 1,
};
// 对象的密封
console.log(Object.seal(obj));
// 判断对象是否被密封
console.log(Object.isSealed(obj));
Object.freeze()
- 冻结一个对象,这个对象再也不能被修改,不能添加、删除、不能修改可枚举性、可配置、可写性、里面的属性值也不可修改。
- 此外,冻结一个对象后该对象的原型也不能被修改。
freeze()
返回和传入的参数相同的对象。
var obj = {
a: 1,
};
console.log(Object.freeze(obj));
console.log(Object.isFrozen(obj));
深度冻结
深度冻结,处理对象上依然是对象的情况
function myFreeze(obj) {
// 先冻结当前对象
Object.freeze(obj);
// 循环冻结对象里的对象
for (var key in obj) {
// 如果是对象,或者是null,让他直接执行一次当前函数。
if (typeof obj[key] === 'object' && obj[key] !== null) {
myFreeze(obj[key]);
}
}
}
Object.is
方法判断两个值是否为同一个值。
// 调用sameValue算法处理三等
console.log(NaN === NaN); //false
console.log(+0 === -0); //true
// 数据类型转换
console.log(NaN == NaN); //false
console.log(+0 == -0); //true
// Object.is
console.log(Object.is(NaN, NaN)); //true
console.log(Object.is(+0, -0)); //falses
console.log({} === {}); //false
console.log(Object.is({} === {})); //false
Object.create
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
返回值
一个新对象,带着指定的原型对象和属性。
这里clone
的原型和obj
是同一个原型
var obj = {
a: 1,
b: 2,
c: 3,
d() {
console.log(this);
},
};
const clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
console.log(clone);
深度拷贝
var obj = {
a: 1,
b: 2,
c: 3,
d: {
e: {
f: {},
},
},
};
const clone = (obj) => Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
console.log(clone(obj));
Object.assign
Object.assign()
拷贝为浅拷贝
let obj = {
a: 1,
};
let tar = {
b: 1,
};
// 目标对象,源对象
let copy = Object.assign(tar, obj);
// 方法返回拷贝对象
console.log(copy);
// 拷贝对象和目标对象是同一个引用
console.log(copy === tar);
// obj 不变 tar 改变
console.log(obj, tar);
对跟对象合并
const tar1 = {
a: 1,
};
const tar2 = {
b: 2,
};
const tar3 = {
c: 3,
};
Object.assign(tar1, tar2, tar3);
console.log(tar1);
属性覆盖
后面的属性会覆盖前面的属性
const tar1 = {
a: 1,
b: 1,
};
const tar2 = {
b: 2,
c: 2,
};
const tar3 = {
c: 3,
};
Object.assign(tar1, tar2, tar3);
console.log(tar1);
原始值调用包装类
var test = Object.assign(1, {
a: 1,
});
console.log(test);
第二个参数不是对象
var test = Object.assign(
{
a: 1,
},
undefined
);
console.log(test);
sources
参数会经过包装类进行包装,如果包装后是可迭代对象就可以使用。
const test1 = 'abc';
const test2 = true;
const test3 = 10;
// 检查属性是否可枚举,不可枚举
const obj = Object.assign({}, test1, test2, test3);
console.log(obj);
console.log(new Object('abc')); // 可遍历
console.log(new Boolean(true)); // 原始值,不可以遍历
console.log(new Number(10)); // 原始值,不可以遍历
拷贝原型、不可枚举
不能拷贝原型和不可枚举属性
var obj = Object.create(
{
foo: 1,
},
{
bar: {
value: 2,
},
baz: {
value: 3,
enumerable: true,
},
}
);
console.log(obj);
// 继承属性和不可枚举属性不能拷贝
var copy = Object.assign({}, obj);
console.log(copy);
同名属性替换
可以被替换同名属性
const target = {
a: {
b: 'c',
d: 'e',
},
};
const sourses = {
a: {
b: 'hello',
},
};
var copy = Object.assign(target, sourses);
console.log(copy);
数组替换的问题
属性名相同就替换,数组的默认下标就是属性名。所以在替换的时候会覆盖原来下标位置的值。
var a = Object.assign([1, 2, 3], [4, 5]);
// [4, 5, 3]
console.log(a);
拷贝取值属性
取值属性没有办法被拷贝
const sourse = {
get foo() {
return 1;
},
};
const target = {};
var copy = Object.assign(target, sourse);
console.log(copy); //foo: 1
给原型扩充属性和方法
可以扩充
function person() {}
var age = 1;
Object.assign(person.prototype, {
eat() {},
age,
});
console.log(person.prototype);
// age: 1
// eat: ƒ eat()
配置默认值
给出了一个默认的参数,如果有参数就替换掉默认值。
const defa = {
url: {
host: 'www.baidu.com',
prot: 8080,
},
};
function test(option) {
// 设置默认值
option = Object.assign({}, defa, option);
console.log(option);
}
test({
url: {
prompt: 8080,
},
});
Object.getOwnPropertyDescriptors()
获取多个属性的属性描述,也可以定义多个属性。
var obj = {};
Object.defineProperties(obj, {
a: {
value: true,
writable: true,
},
b: {
value: 'hello',
writable: false,
},
});
console.log(obj);
console.log(Object.getOwnPropertyDescriptors(obj));
完全拷贝一个对象
defineProperties
和getOwnPropertyDescriptors
就是为了解决复制 get 和 set 而存在的
const sourse = {
set foo(value) {
console.log(value);
},
};
const tar = {};
Object.defineProperties(tar, Object.getOwnPropertyDescriptors(sourse));
console.log(Object.getOwnPropertyDescriptors(tar));
部署对象
// 方式1
const obj1 = {
a: 1,
};
console.log(obj1);
// 方式2
var prot = {
a: '原型绑定',
};
const obj2 = Object.create(prot);
obj2.foo = 123;
console.log(obj2);
// 方式3 指定原型,部署属性
const obj3 = Object.assign(Object.create(prot), {
foo1: '123',
});
console.log(obj3);
// 方式4
const obj4 = Object.create(
prot,
Object.getOwnPropertyDescriptors({
foo: '345',
})
);
console.log(obj4);
Symbol()
一个不重复的原始类型,永远不会重复的字符串
var a = Symbol('a');
var b = Symbol('a');
console.log(a === b); //false
可以被迭代可以被复制
var test = Object.assign(
{
a: 'b',
},
{
[Symbol('c')]: 'd',
}
);
console.log(test);