一、对象的创建
// 第一种 最简单的写法
let obj = { a: 1 }
console.log(obj.a) // 1
typeof obj.toString // 'function'
// 第二种Object.create()继承一个对象,并创建一个新的对象
let obj2 = Object.create({ a: 1 })
console.log(obj2.a) // 1
console.log(obj2)//{} 这个obj2是空对象,因为a属性是一个继承属性
typeof obj2.toString // 'function'
// 第三种
let obj3 = Object.create(null)
typeof obj3.toString // 'undefined'
Object.create(null)来创建一个空对象,其好处不用考虑会和原型链上的属性重名问题
二、Object.defineProperty()定义对象属性
Object.defineProperty(obj,prop,descriptor)中的descriptor有如下几种参数:
configurable 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对
应的对象上被删除。默认为 false
enumerable 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false
value 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
get 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方
法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
默认为 undefined。
set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该
方法将接受唯一参数,即该属性新的参数值。默认为 undefined
创建对象的同时,对象上会默认设置当前对象的枚举类型值,如果不设置,默认所有枚举类型均为false,
注意:在 descriptor 中不能同时设置访问器 (get 和 set) 和 value。
举个栗子:
Object.defineProperty(obj,prop,
configurable: true,
enumerable: true,
writable: true,
value: '',
get: function() {
},
set: function() {
}
)
三、Object.getOwnPropertyDescriptor查看对象上属性的枚举类型值
// 如果不设置枚举类型,默认都是false
let obj = {}
Object.defineProperty(obj, 'name', {
value : "wqzwh"
})
Object.getOwnPropertyDescriptor(obj, 'name')
// {value: "wqzwh", writable: false, enumerable: false, configurable: false}
let obj2 = {}
Object.defineProperty(obj2, 'name', {
enumerable: true,
writable: true,
value : "wqzwh"
})
Object.getOwnPropertyDescriptor(obj2, 'name')
// {value: "wqzwh", writable: true, enumerable: true, configurable: false}
四、Object.keys()获取对象的键
通过Object.keys()来获取对象的key,必须将enumerable设置为true才能获取,否则返回是空数组
let obj = {}
Object.defineProperty(obj, 'name', {
enumerable: true,
value : "wqzwh"
})
Object.keys(obj) // ['name']
五、Object.propertyIsEnumerable()判断属性是否为可枚举属性
let obj = {}
Object.defineProperty(obj, 'name', {
value : "wqzwh"
})
obj.propertyIsEnumerable('name') // false
let obj = {}
Object.defineProperty(obj, 'name', {
enumerable: true,
value : "wqzwh"
})
obj.propertyIsEnumerable('name') // true
六、Object.hasOwnProperty()检测一个对象是否含有特定的自身属性
1.通过hasOwnProperty来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会忽略掉那些 从原型链上继承到的属性。
2如果继承的对象属性是通过Object.defineProperty创建的,并且enumerable未设置成true,那么for in依然不能枚举出原型上的属性。
// 使用Object.defineProperty创建对象属性
let obj = {}
Object.defineProperty(obj, 'name', {
value : "wqzwh",
enumerable: true
})
let obj2 = Object.create(obj)
obj2.age = 20
for (key in obj2) {
console.log(key); // age, name
}
for (key in obj2) {
if (obj2.hasOwnProperty(key)) {
console.log(key); // age
}
}
// 普通创建属性
let obj = {}
obj.name = 'wqzwh'
let obj2 = Object.create(obj)
obj2.age = 20
for (key in obj2) {
console.log(key); // age, name
}
for (key in obj2) {
if (obj2.hasOwnProperty(key)) {
console.log(key); // age
}
}
七、get/set方法来检测属性变化
function foo() {}
Object.defineProperty(foo.prototype, 'z',
{
get: function(){
return 1
}
}
)
let obj = new foo();
console.log(obj.z) // 1
obj.z = 10
console.log(obj.z) // 1
这个是z属性是foo.prototype上的属性并且有get方法,对于第二次通过obj.z = 10并不会在obj本身创建z属性,而是直接原型触发上的get方法。
如果在创建当前对象上定义z属性,并且设置writable和configurable为true,那么就可以改变z属性的值,并且
删除z属性后再次访问obj.z仍然是1,测试代码如下:
function foo() {}
Object.defineProperty(foo.prototype, 'z',
{
get: function(){
return 1
}
}
)
let obj = new foo();
console.log(obj.z) // 1
Object.defineProperty(obj, 'z',
{
value: 100,
writable: true,
configurable: true
}
)
console.log(obj.z) // 100
obj.z = 300
console.log(obj.z) // 300
delete obj.z
console.log(obj.z) // 1
八、对象标签proto
let obj = {x: 1, y: 2}
obj.__proto__.z = 3
console.log(obj.z) // 3
九、Object.preventExtensions方法用于锁住对象属性,Object.isExtensible用于判断对象是否可以被拓展
Object.preventExtensions方法用于锁住对象属性,使其不能够拓展,也就是不能增加新的属性,但是属性的值仍然可以更改,也可以把属性删除,Object.isExtensible用于判断对象是否可以被拓展.
let obj = {x : 1, y : 2};
Object.isExtensible(obj); // true
Object.preventExtensions(obj);
Object.isExtensible(obj); // false
obj.z = 1;
obj.z; // undefined, add new property failed
Object.getOwnPropertyDescriptor(obj, 'x');
// Object {value: 1, writable: true, enumerable: true, configurable: true}
十、Object.seal方法用于把对象密封
Object.seal方法用于把对象密封,也就是让对象既不可以拓展也不可以删除属性(把每个属性的configurable设为false),单数属性值仍然可以修改,Object.isSealed由于判断对象是否被密封
let obj = {x : 1, y : 2};
Object.seal(obj);
Object.getOwnPropertyDescriptor(obj, 'x');
// Object {value: 1, writable: true, enumerable: true, configurable: false}
Object.isSealed(obj); // true
十一、Object.freeze完全冻结对象
Object.freeze完全冻结对象,在seal的基础上,属性值也不可以修改(每个属性的wirtable也被设为false),Object.isFrozen判断对象是否被冻结
let obj = {x : 1, y : 2};
Object.freeze(obj);
Object.getOwnPropertyDescriptor(obj, 'x');
// Object {value: 1, writable: false, enumerable: true, configurable: false}
Object.isFrozen(obj); // true
![](https://img.haomeiwen.com/i7096759/4e736ba7754b52db.png)
},
转自:掘金
作者:wqzwh
链接:https://juejin.im/post/5b4ad441f265da0f7d4eeb7a
网友评论