这里介绍的方法是作为Object构造函数的方法,不会被其他对象继承,所以这些方法只能Object调用。
为什么对象不能调用Object的方法?
Object.create()
作用:创建一个新对象
参数:一个用作新对象原型的对象,一个为新对象定义额外属性的对象(可选)。
返回值:新对象
// 一个简易的create()方法
function create(proto){
function F(){}
F.prototype = proto;
return new F;
}
Object.getOwnPropertyDescriptor()
作用:获取对象属性的描述符对象
参数:对象,对象的属性名称(string类型)
返回值:对象属性的描述符对象,没找到对象属性则返回undefined(不会在原型链上寻找属性)
var o = {};
o.x=1;
console.log(Object.getOwnPropertyDescriptor(o,"x"));
描述符对象描述的是对象属性是否可被for in枚举(enumerable),属性值是否可改变(writable),属性值是否可被delete删除(configurable)等。
以字面量的形式给对象o添加的属性,描述符对象布尔值都为true
ES6默认内置对象的原型对象属性不可枚举(enumerable值为false)。
Object.defineProperty()
作用:定义或修改对象的属性的特性
参数:属性所在的对象,属性的名称(string类型),一个描述符对象(上面方法的描述符对象)
返回值:属性所在的对象
var o ={};
Object.defineProperty(o,"y",{}); //描述符对象为空
console.log(Object.getOwnPropertyDescriptor(o,"y"));
可以看到以defineProperty()方法配置属性时的默认值(布尔值都为false)
我们可以自己配置这些特性值
Object.defineProperty(o, "z", {
enumerable: true,
configurable: false,
writable: false,
value: "test"
});
Object.defineProperties()
作用:和Object.defineProperty()方法类似,不过能同时配置多个对象属性的特性。
参数:要在其上定义或修改属性的对象,对象
返回值:参数的第一个对象
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
});
Object.getPrototypeOf()
作用:获取对象的原型对象
参数:对象
返回值:对象的原型对象
var a = Object.prototype;
var b = Object.getPrototypeOf(String.prototype);
console.log(a===b); //true
可以看出String的原型对象的原型对象和Object.prototype相等,说明string对象是继承Object对象的。(所有对象都是继承Object)
对象中有一个_ proto _(前后各两个下划线,没有空格,这个编辑器必须打空格才能输出)属性。
这个属性指向的是对象的原型对象
ES6推荐使用Object.getPrototypeOf()方法获取对象原型
Object.setPrototypeOf()
作用:设置对象的原型对象
参数:要设置对象原型的对象,原型对象
返回值:参数的第一个对象
ES6推荐使用Object.setPrototypeOf()方法设置对象原型,而不是使用对象的 _ proto _
下面介绍Object提供用来遍历对象的方法
为了减少复杂,这些方法都不会遍历原型链上的属性(上面的方法也是)。
Object.getOwnPropertyNames()
作用:返回对象自身拥有的所有可枚举或不可枚举属性的属性名
参数:对象
返回值:属性名所组成的字符串数组
console.log(Object.getOwnPropertyNames(Array.prototype));
此方法不能返回对象symbol值的属性
Object.keys()
作用:返回对象自身所有可枚举的属性名
参数:对象
返回值:属性名所组成的字符串数组
console.log(Object.keys(Array.prototype)); //[]
内置对象的原型对象的属性都是不可枚举的,所以返回空数组
此方法不能返回对象的键为symbol值的属性
Object.getOwnPropertySymbols()
作用:返回对象自身的所有键为 Symbol 属性的属性
参数:对象
返回值:属性所组成的数组
var obj = {};
var sym = Symbol('foo');
obj[sym] = 1;
console.log(Object.getOwnPropertySymbols(obj)); //[Symbol(foo)]
注意:此方法不是返回属性值,返回的是这个属性名,不过这个属性名是Symbol值而已。
Object.values()
作用:返回对象所有可枚举的属性值。值的顺序与使用for…in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
参数:对象
返回值:属性值所组成的数组
var obj = {};
obj.x = 1;
obj.y = 2;
Object.defineProperty(obj,"z",{
enumerable: false,
value: 3
})
console.log(Object.values(obj)); //[1,2]
此方法不能返回对象的键为symbol值的属性
Object.entries()
作用:返回对象所有可枚举的属性
参数:对象
返回值:对象自身可枚举属性的键值对数组
var obj = {};
obj.x = 1;
obj.y = 2;
Object.defineProperty(obj,"z",{
enumerable: false,
value: 3
})
console.log(Object.entries(obj)); //[["x", 1],["y", 2]]
此方法不能返回对象键为symbol值的属性
总结遍历对象的方法:
- for in会遍历原型链上所有的可枚举的属性,Object提供的方法不会遍历原型链上的属性
- Object.getOwnPropertyNames() 和Object.keys() 方法用来遍历对象的属性名,区别是前者可以遍历不可枚举的属性
- Object.getOwnPropertySymbols() 方法只能用来遍历对象的键为Symbol值的属性
- Object.values()方法用来遍历对象可枚举属性的属性值
- Object.entries()方法返回的是对象可枚举属性的键值对
上面方法遍历对象属性的顺序一般是:
首先遍历所有属性名为数值的属性,按照数字排序。
其次遍历所有属性名为字符串的属性,按照生成时间排序。
最后遍历所有属性名为Symbol值的属性,按照生成时间排序。
上面的方法不能同时遍历对象上的所有属性,ES6提供了一种方法,用来遍历对象所有属性(包括可枚举和不可枚举,键为Symbol值的属性)
Reflect.ownKeys()
作用:遍历对象的所有属性(不包括原型链上的属性)
参数:对象
返回值:属性名所组成的数组(Symbol属性名是Symbol值)
Object.prototype的方法(可被继承,所有对象都可以使用)
Object.prototype.hasOwnProperty()
返回一个布尔值 ,表示某个对象是否含有指定的属性,而且此属性非原型链继承的。
Object.prototype.isPrototypeOf()
返回一个布尔值,表示指定的对象是否在本对象的原型链中。
Object.prototype.propertyIsEnumerable()
判断指定属性是否可枚举,内部属性设置参见 ECMAScript [[Enumerable]] attribute 。不会去判断继承的属性和方法。