跳到主要内容

获取属性名称

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()

  1. 冻结一个对象,这个对象再也不能被修改,不能添加、删除、不能修改可枚举性、可配置、可写性、里面的属性值也不可修改。
  2. 此外,冻结一个对象后该对象的原型也不能被修改。
  3. 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));

完全拷贝一个对象

definePropertiesgetOwnPropertyDescriptors就是为了解决复制 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);