涉及API:
new Object()
Object.create()
Object.defineProperty()
Object.defineProperties()
Object.assign()
Object.toString()
Object.keys()
Object.values()
创建对象
// 创建对象:
let obj = { name: "js", age: 27 };
let obj2 = new Object();
obj2.name = "js";
obj2.age = 27;
let obj3_3 = { name: "js" }
let obj3 = Object.create(
obj3_3,
{
age: { value: 27, writable: true },
}
);
console.log(obj);
console.log(obj2);
console.log(obj3, obj3.age, obj3.name);
/**
*
Object.create() 有两个参数:Object.create(proto, [propertiesObject])
proto : 必须,表示新建对象的原型对象。
即该参数会被赋值到目标对象(即新对象,或说是最后返回的对象)的原型上。
该参数可以是null, 对象, 函数的 prototype 属性
注意:创建空的对象时需传null , 否则会抛出 TypeError 异常
propertiesObject: 可选,添加到新创建对象的可枚举属性。
( 即其自身的属性,而不是原型链上的枚举属性 ) 对象的属性描述符以及相应的属性名称。
这些属性对应Object.defineProperties()的第二个参数。
*/
给对象添加属性
/**
API: Object.defineProperty
value:被定义的属性的值,默认为undefined;
writable: 是否可以被重写(被重新赋值),
enumerable:是否可以被枚举(使用for...in或者Object.keys()),
configurable: 是否可以删除目标属性或者是否可以再次修改属性的特性(writable,configurable,enumerable)
get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。
当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象
(由于继承关系,这里的this并不一定是定义该属性的对象)。默认为 undefined。
set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。
当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认为 undefined。
*/
// 1.添加一个数据属性
Object.defineProperty(obj, "newAddProperty", {
value: 101,
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.newAddProperty) // 101
// 一次添加多个属性
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true,
enumerable: true,
configurable: true
},
'property2': {
value: 'Hello',
writable: false,
enumerable: true,
configurable: true
}
// ...
});
修改属性
// 2.修改数据属性
Object.defineProperty(obj, "newAddProperty", {
writable:false
});
添加访问器属性
//添加访问器属性
Object.defineProperty(obj2, "newAccessorProperty", {
set: function (x) {
this.name = x;
},
get: function () {
return this.name;
},
enumerable: true,
configurable: true
});
console.log(obj2.name)
obj2.newAccessorProperty = "newAccessorProperty"
console.log(obj2.name,obj2.newAccessorProperty)
对象合并<浅拷贝>
// assign 对象合并<浅拷贝>
/**
* 对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
* 拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),
* 也不拷贝不可枚举的属性(enumerable: false)
*/
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
// 特殊情况
let obj4 = Object.assign([1, 2, 3], [4, 5])
console.log(obj4)
// Object.assign 把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性4覆盖了目标数组的 0 号属性1
// 换言之 数组[1,2,3]的索引0被 后面数组[4,5]的0号索引对应的值 4覆盖掉
// 即 4覆盖1, 5覆盖2
// Object.assign(obj, undefined) === obj // true
// Object.assign(obj, null) === obj // true
// 报错,因为 null 和 undefined 无法被转换成 object
// let a = null
// Object.assign(a)
// let b = undefined
// Object.assign(b)
Object.toString
// Object.toString() 面试题
var a = {};
var b = {name:"ZS"};
var c = {};
c[a] = "demo1";
c[b] = "demo2";
console.log(c[a]); // demo2
console.log(c); // { '[object Object]': 'demo2' }
// c[a] 打印为demo2 是因为:
// c[a],c[b]隐式的将对象a,b使用了toString()方法进行了转换,然后再对属性赋值
console.log(a.toString());//[object Object]
console.log(a.toString() === b.toString());//true 说明返回值是一样的
console.log(c[a]);//demo2 被c[b]复写结果的缘故
var obj = {}
var m = "testkey"
obj[m]="testvalue"
console.log(obj) // {"testkey":"testvalue"}
obj[m] 如果m变量是一个字符串,使用[m]取得是变量m的值作为obj的key使用
获取对象属性
// 获取对象属性
console.log(Object.keys(obj))
console.log(Object.values(obj))