总结Object的方法

这里介绍的方法是作为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 。不会去判断继承的属性和方法。

    参考链接:Object - JavaScript | MDN

    ### JavaScriptObject.keys、Object.values和Object.entries的使用方法及区别 #### 方法定义与功能 `Object.keys()` 返回一个包含给定对象自身所有可枚举属性键名的数组[^1]。 例如,如果存在如下对象: ```javascript const obj = { a: 1, b: 2, c: 3 }; console.log(Object.keys(obj)); // 输出: ["a", "b", "c"] ``` `Object.values()` 则返回一个包含给定对象自身所有可枚举属性值的数组[^2]。 继续以上述对象为例: ```javascript console.log(Object.values(obj)); // 输出: [1, 2, 3] ``` 而 `Object.entries()` 返回的是一个二维数组,每一项是一个 `[key, value]` 对应关系的数组[^3]。同样基于前述对象: ```javascript console.log(Object.entries(obj)); // 输出: [["a", 1], ["b", 2], ["c", 3]] ``` #### 可枚举性的影响 当通过 `Object.defineProperty()` 修改某个属性为不可枚举时,这些方法的行为会发生变化。例如: ```javascript var obj = { age: 18, name: 'zhangsan' }; console.log("======修改前======"); console.log(Object.keys(obj)); // 输出: ['age', 'name'] console.log(Object.values(obj)); // 输出: [18, 'zhangsan'] console.log(Object.entries(obj)); // 输出: [['age', 18], ['name', 'zhangsan']] Object.defineProperty(obj, "age", { value: 19, enumerable: false // 将 age 属性设置为不可枚举 }); console.log("======修改后======"); console.log(Object.keys(obj)); // 输出: ['name'] console.log(Object.values(obj)); // 输出: ['zhangsan'] console.log(Object.entries(obj)); // 输出: [['name', 'zhangsan']] ``` 这里可以看到,一旦将 `age` 设置为不可枚举,则它不再被 `Object.keys()`、`Object.values()` 或者 `Object.entries()` 所返回[^3]。 #### 实际应用场景举例 考虑一个购物车的例子,其中存储了几种商品及其价格: ```javascript const shoppingCart = { apple: 0.75, banana: 0.5, orange: 0.65 }; // 获取所有商品名称 console.log(Object.keys(shoppingCart)); // 输出: ["apple", "banana", "orange"] // 获取所有商品的价格 console.log(Object.values(shoppingCart)); // 输出: [0.75, 0.5, 0.65] // 获取每件商品的名字与其对应的价格 console.log(Object.entries(shoppingCart)); /* 输出: [ ["apple", 0.75], ["banana", 0.5], ["orange", 0.65] ] */ ``` 这种方法非常适合于遍历对象或者将其数据结构化以便进一步处理[^5]。 #### 总结差异 | 方法 | 返回结果 | 数据形式 | |-------------------|------------------------------|------------------| | `Object.keys()` | 对象的所有可枚举属性键 | 字符串数组 | | `Object.values()` | 对象的所有可枚举属性值 | 值类型的数组 | | `Object.entries()`| 对象的所有可枚举键值对组合 | 数组嵌套数组的形式 |
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值