前言
最近工作有点空闲时间,想整理下之前学过的对象中的相关方法的使用,因为对象中的方法太多了,梳理的过程可以加深自己的理解。
创建对象
平常我们创建对象都是使用字面量的形式,其实创建对象还可以通过new Object()的形式创建,这两种创建方式是一样的。
1.通过new Object()创建
var obj = new Object() obj.name = "aaa" obj.age = 18
2. 字面量形式
var obj = { name: "aaa", age: 18 }
delete对象属性
1.delete用来删除对象的属性,删除成功后返回true。用delete删除一个不存在的属性时也不报错,而且返回true。
const obj = { age: '18', address: '2344' }
console.log(delete(obj.sss)); // true
2.delete无法删除继承的属性,例如toString属性,即使delete返回true,该属性还是没有被删除可以被读取。
const obj = { age: '18', address: '2344' }
console.log(delete(obj.toString)); // true
console.log("toString" in obj) // true
3 .delete删除一个数组元素,会形成空位,并且不会影响数组的length值
const arr = [2,3,4,5,6]
delete(arr[0])
console.log(arr); // [ <1 empty item>, 3, 4, 5, 6 ]
console.log(arr.length); // 5
Object()
将任意值转为对象,如果参数为空(或者为undefined和null),Object()返回一个空对象;如果参数是一个对象,它总是返回该对象,即不用转换。
var arr = [];
arr === Object(arr); // true
可以用此方法封装一个判断变量是否为对象的方法:
function isObject(value) {
return value === Object(value);
}
isObject([]) // true
isObject(true) // false
Object.seal()
禁止对象配置和删除属性。
Object.freeze()
冻结对象,不允许修改现有属性。
Object.preventExtensions()
禁止对象继续添加新的属性
in/for in/for of
in操作符用来判断某个属性是否在对象或者对象的原型上,包括不可遍历属性。 for in操作符用来遍历对象的所有可遍历属性,包括继承属性。继承的toString属性不会被遍历是因为默认不可遍历。 for of操作符不能用来遍历普通对象,只可以遍历可迭代对象,什么是可迭代对象以后我会详细说。
const obj = { age: '18', address: '2344' }
console.log('address' in obj); // true
for (const k in obj) {
console.log(k); // age address
}
hasOwnProperty
判断对象中是否有这个属性,包括不可遍历属性,不包括继承属性。
const obj = { age: '18', address: '2344' }
console.log(obj.hasOwnProperty('address')); // true
console.log(obj.hasOwnProperty('toString')); // false
这个方法可以和for in结合使用
const obj = {xxxx}
for (const k in obj) {
if (obj.hasOwnProperty(k)) { // 这里可以去除掉可遍历的继承属性
// 逻辑处理......
}
}
Object.getOwnPropertyNames()
返回一个字符串数组,数组成员是对象键名,不包括继承属性,包括不可遍历属性。
Object.keys()
返回一个字符串数组,数组成员是对象键名,不包括继承属性,不包括不可遍历属性。
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptor(obj, "name") // 获取某一个属性的属性描述符
Object.getOwnPropertyDescriptors(obj) // 获取对象的所有属性描述符
Object.defineProperty()
在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
# 接收三个参数
Object.defineProperty(obj, prop, descriptor)
1.obj要定义属性的对象 2.prop要定义或修改的属性的名称或Symbol 3.descriptor定义或修改的属性描述符
# 属性描述符
value:属性的value值,读取属性时会返回该值,修改属性时会对其进行修改,默认值为undefined
Writable:表示是否可以修改属性的值
Configurable: 属性是否可以通过delete删除属性,是否可以修改它的特性
Enumerable:属性是否可以通过for-in或者Object.keys()返回该属性
get:获取属性时会执行的函数。默认为undefined
set:设置属性时会执行的函数。默认为undefined
# 属性描述符注意项
1. 在configurable:false时,还是可以把writable由true改为false,不可以由false改为true
2. 取值函数get不能接受参数,存值函数set只能接受一个参数
3. get与set属性和writable: true value属性不能同时存在
当使用Object.defineProperty()方法定义对象属性时,属性描述符的默认值都为false
const obj = {}
Object.defineProperty(obj, 'age', { value: 18 })
console.log(obj); // {},因为属性描述符中Enumerable为false,不可遍历
console.log(Object.getOwnPropertyDescriptor(obj, 'age'));
// { value: 18, writable: false, enumerable: false, configurable: false }
然而当使用字面量形式定义对象属性时,属性描述符的默认值都为true
const obj = {}
obj.age = 18
console.log(obj); // { age: 18 }
console.log(Object.getOwnPropertyDescriptor(obj, 'age'));
// { value: 18, writable: true, enumerable: true, configurable: true }
Object.defineProperties()
可以同时定义多个属性。
const obj = {}
Object.defineProperties(obj, {
name: {
value: '哈哈'
},
age: {
value: 18
}
})
console.log(Object.getOwnPropertyDescriptors(obj));
// 打印结果如下
{
name: {
value: '哈哈',
writable: false,
enumerable: false,
configurable: false
},
age: {
value: 18,
writable: false,
enumerable: false,
configurable: false
}
}
Object.getPrototypeOf()
获取对象的原型。
const obj = {} // 相当于 const obj = new Object()
console.log(Object.getPrototypeOf(obj) === obj.__proto__); // true
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true
Object.setPtototypeOf()
Object.setPtototypeOf(newObj, obj) 就是将obj对象作为newObj对象的原型。
const obj = {}
const newObj = {}
Object.setPrototypeOf(newObj, obj)
console.log(Object.getPrototypeOf(newObj) === obj); // true
instanceof
用于检测构造函数的pototype,是否出现在某个实例对象的原型链上,这个instanceof的原理以后会详细讲。
console.log(stu instanceof Student) // 检测Student的pototype是否在stu对象的原型链上
class Person {
constructor(age) {
this.age = age
}
}
const ss = new Person()
console.log(ss instanceof Person); // true
console.log(ss instanceof Object); // true
Object.create()
我忘了是干啥的了,但是会使用,参数不能为空。还有这个方法在以后讲的继承中会用到。
这个方法好像是以传入的参数作为创建的对象的原型,并返回一个空对象。
const obj = { name: "why", age: 18}
const info = Object.create(obj) // obj对象是info对象的原型
console.log(info); // {}
console.log(Object.getPrototypeOf(info) === obj); // true
// 传入的参数是null时有点特殊
let obj = Object.create(null) // {},就是生成了一个空对象.该对象没有valueOf和toString方法。
Object.create(null) instanceof Object // false,因为返回的空对象的原型是null,已经处于原型链最顶层了
isPrototypeOf
用于检测某个对象,是否出现在某个实例对象的原型链上。
var obj = { name: "why", age: 18}
var info = Object.create(obj)
console.log(obj.isPrototypeOf(info))
总结
上述都是Object常用的一些方法,有一些没使用过,有一些经常使用,比如Object.create()。后面应该还有继承,浅拷贝,深拷贝,判断对象是否相同等一些内容。