◆

JavaScript Object 对象属性与方法 API 详解

2023-02-02 01:370

Object 对象的原生方法

分成两类: Object 本身的方法(静态方法)与 Object 的实例方法。

Object 对象本身的方法

所谓“本身的方法”就是直接定义在 Object 对象的方法。

Object.print = function (o) {
  console.log(o);
};

Object 的实例方法

所谓实例方法就是定义在 Object 原型对象 Object.prototype 上的方法。它可以被 Object 实例直接使用

Object.prototype.print = function () {
  console.log(this);
};

var obj = new Object();
obj.print(); // Object

Object() 作为函数使用

Object 本身是一个函数,可以当作工具方法使用,将任意值转为对象。这个方法常用于保证某个值一定是对象。

如果参数为空(或者为 undefined 和 null),Object() 返回一个空对象。

var obj = Object();
// 等同于
var obj = Object(undefined);
var obj = Object(null);

obj instanceof Object; // true

如果参数是原始类型的值,Object 方法将其转为对应的包装对象的实例

var obj = Object(1);
obj instanceof Object; // true
obj instanceof Number; // true

var obj = Object('foo');
obj instanceof Object; // true
obj instanceof String; // true

var obj = Object(true);
obj instanceof Object; // true
obj instanceof Boolean; // true

如果 Object 方法的参数是一个对象,它总是返回该对象,即不用转换。

var arr = [];
var obj = Object(arr); // 返回原数组
obj === arr; // true

var value = {};
var obj = Object(value); // 返回原对象
obj === value; // true

var fn = function () {};
var obj = Object(fn); // 返回原函数
obj === fn; // true

利用这一点,可以写一个判断变量是否为对象的函数。

function isObject(value) {
  return value === Object(value);
}

isObject([]); // true
isObject(true); // false

Object 构造函数

Object 构造函数的首要用途,是直接通过它来生成新对象。

var obj = new Object();

通过 var obj = new Object() 的写法生成新对象,与字面量的写法 var obj = {} 是等价的,后者只是前者的一种简便写法

Object 构造函数的用法与工具方法很相似,几乎一模一样。使用时,可以接受一个参数,如果该参数是一个对象,则直接返回这个对象;如果是一个原始类型的值,则返回该值对应的包装对象

var o1 = { a: 1 };
var o2 = new Object(o1);
o1 === o2; // true

var obj = new Object(123);
obj instanceof Number; // true

Object 的静态方法

Object.keys()

返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名,只返回可枚举的属性。

var obj = {
  p1: 123,
  p2: 456,
};

Object.keys(obj); // ["p1", "p2"]

Object.getOwnPropertyNames

返回一个数组,包含了该对象自身的所有属性名,可返回不可枚举的属性名

下面代码中数组的 length 属性是不可枚举的属性,所以只出现在 Object.getOwnPropertyNames 方法的返回结果中

var a = ['Hello', 'World'];

Object.keys(a); // ["0", "1"]
Object.getOwnPropertyNames(a); // ["0", "1", "length"]

Object.getOwnPropertyDescriptor() & Object.getOwnPropertyDescriptors()

  • Object.getOwnPropertyDescriptor: 返回指定对象上一个自有属性对应的属性描述符。
  • Object.getOwnPropertyDescriptors: 获取一个对象的所有自身属性的描述符。
const object1 = {
  property1: 42,
};

Object.defineProperty(object1, 'name', {
  value: 'wfly',
  enumerable: false,
});

const descriptor = Object.getOwnPropertyDescriptor(object1, 'property1');
console.log(descriptor);

console.log(Object.getOwnPropertyDescriptors(object1));
Object属性与方法api详解

Object.preventExtensions()

防止对象扩展,永远不能再添加新的属性(阻止添加自身的属性,但其对象类型的原型依然可以添加新的属性),返回原对象。

var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
console.log(nonExtensible);

nonExtensible.test = 'test'; // 无效
nonExtensible.__proto__.test = 'test'; // 原型可以添加新的属性
nonExtensible.__proto__ = { test: 'test' }; // 原型是不可变

Object.defineProperty(nonExtensible, 'new', { value: 8675309 }); // 抛出 TypeError 异常

Object.isExtensible()

判断对象是否可扩展,是否可以在它上面添加新的属性。

在 ES5 中,如果参数不是一个对象类型,将抛出一个 TypeError 异常。在 ES6 中,non-object 参数将被视为一个不可扩展的普通对象,因此会返回 false。

var empty = {};
Object.isExtensible(empty); // true

// Object.preventExtensions 使对象不可扩展。
Object.preventExtensions(empty);
Object.isExtensible(empty); // false

// 密封对象是不可扩展的。
var sealed = Object.seal({});
Object.isExtensible(sealed); // false

// 冻结对象也是不可扩展。
var frozen = Object.freeze({});
Object.isExtensible(frozen); // false

Object.seal()

禁止对象配置。

Object.isSealed()

判断一个对象是否可配置。

Object.freeze()

冻结一个对象。冻结了的对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。

  • 返回和传入的参数相同的对象。
var obj = {
  prop: function () {},
  age: 18,
  person: {
    name: 'wfly',
  },
  foods: {
    apple: '苹果',
  },
};

var o = Object.freeze(obj);
o === obj; // true
Object.isFrozen(obj); // true

delete obj.prop;
obj.age = 8;
obj.person.name = 'wf';
obj.foods = 'banner';

console.log(obj); // 没有任何改变
Object属性与方法api详解

如图所示结果会发现,冻结对象也只是冻结对象的引用,所以 obj.person.name 的值被改变了,要想对象真正的不可变,要递归冻结所有对象以及子对象

Object.isFrozen()

判断一个对象是否被冻结,一个对象是冻结的是指它不可扩展,所有属性都是不可配置的,且所有数据属性(即没有 getter 或 setter 组件的访问器的属性)都是不可写的。

Object.getPrototypeOf()

返回指定对象的原型(内部 [[Prototype]] 属性的值),如果没有继承属性,则返回 null。

const prototype1 = {};
const object1 = Object.create(prototype1);
console.log(Object.getPrototypeOf(object1) === prototype1); // true

Object.entries

返回一个给定对象自身可枚举属性的键值对数组

const myObj = Object.create(
  {},
  {
    getFoo: {
      value() {
        return this.foo;
      },
      enumerable: true,
    },
  },
);
myObj.foo = 'bar';
console.log(Object.entries(myObj));
Object属性与方法api详解

非对象数据类型会被强制转化为对象

Object.entries('foo');
Object属性与方法api详解

将 Object 转换为 Map

var obj = { foo: 'bar', baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map);
Object属性与方法api详解

Object.fromEntries

接收一个键值对的列表参数(这个参数应该是一个能够实现 iterator 方法的的对象),并返回一个带有这些键值对的新对象,它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。

  • Map 转化为 Object
const map = new Map([
  ['foo', 'bar'],
  ['baz', 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
  • Array 转化为 Object
const arr = [
  ['0', 'a'],
  ['1', 'b'],
  ['2', 'c'],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }

Object.hasOwn()

接受一个字符串作为参数,返回一个布尔值,表示该实例对象自身是否具有该属性,旨在取代 Object.prototype.hasOwnProperty()。

它比 Object.prototype.hasOwnProperty() 存在哪些优势

  • 对象重新定义 hasOwnProperty 方法
const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: 'The dragons be out of office',
};
foo.hasOwnProperty('bar'); // false
Object.hasOwn(foo, 'bar'); // true
  • Object.create(null) 创建一个为空的原型对象
const foo = Object.create(null);
foo.prop = 'exists';
Object.hasOwn(foo, 'prop'); // true

// hasOwnProperty 原本是 Object 原型上的方法,但是用 Object.create(null) 创建会导致这个对象没有原型上的方法
foo.hasOwnProperty('prop'); // foo.hasOwnProperty is not a function

Object 的实例方法

定义在 Object.prototype 对象上的方法

Object.prototype.valueOf()

Object.prototype.toString()

Object.prototype.hasOwnProperty()

接受一个字符串作为参数,返回一个布尔值,表示该实例对象自身是否具有该属性。

var obj = {
  p: 123,
};

obj.hasOwnProperty('p'); // true
obj.hasOwnProperty('toString'); // false
💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEJavaScript Object 对象属性与方法 API 详解加载中