recursal/MDN huggingface dataset:
Object.prototype.toLocaleString()
=================================

**`toLocaleString()`** 方法返回一个表示对象的字符串。该方法旨在由派生对象重写，以达到其特定于语言环境的目的。

尝试一下
----

语法
--


```js
toLocaleString()
```

### 参数

没有参数。但是，重写此方法的所有对象最多只能接受两个参数，分别对应于 `locales` 和 `options`，例如 `Date.prototype.toLocaleString`。这些参数位置不应该用于任何其他目的。

### 返回值

调用 `this.toString()` 的返回值。

描述
--

所有继承 `Object.prototype`（也就是说，除了 `null` 原型对象）的对象都继承了 `toLocaleString()` 方法。`Object` 的 `toLocaleString` 返回调用 `this.toString()` 的结果。

提供此方法是为了给对象一个通用的 `toLocaleString` 方法，即使不是所有对象都会使用它。在核心语言中，这些内置对象重写了 `toLocaleString` 以提供特定于语言环境的格式：

* `Array`：`Array.prototype.toLocaleString()`
* `Number`：`Number.prototype.toLocaleString()`
* `Date`：`Date.prototype.toLocaleString()`
* `TypedArray`：`TypedArray.prototype.toLocaleString()`
* `BigInt`：`BigInt.prototype.toLocaleString()`
示例
--

### 使用基本的 toLocaleString() 方法

基本的 `toLocaleString()` 方法只是简单地调用 `toString()`。


```js
const obj = {
  toString() {
    return "My Object";
  },
};
console.log(obj.toLocaleString()); // "My Object"
```

### Array 重写的 toLocaleString()

`Array.prototype.toLocaleString()` 用于将数组值打印成字符串，通过调用每个元素的 `toLocaleString()` 方法，并使用特定于语言环境的分隔符拼接。例如：


```js
const testArray = [4, 7, 10];

const euroPrices = testArray.toLocaleString("fr", {
  style: "currency",
  currency: "EUR",
});
// "4,00 €,7,00 €,10,00 €"
```

### Date 重写的 toLocaleString()

`Date.prototype.toLocaleString()` 用于打印成更适合特定语言环境的日期显示。例如：


```js
const testDate = new Date();
// "Fri May 29 2020 18:04:24 GMT+0100 (British Summer Time)"

const deDate = testDate.toLocaleString("de");
// "29.5.2020, 18:04:24"

const frDate = testDate.toLocaleString("fr");
// "29/05/2020, 18:04:24"
```

### Number 重写的 toLocaleString()

`Number.prototype.toLocaleString()` 用于打印成更适合特定语言环境的数字显示，例如使用正确的分隔符。例如：


```js
const testNumber = 2901234564;
// "2901234564"

const deNumber = testNumber.toLocaleString("de");
// "2.901.234.564"

const frNumber = testNumber.toLocaleString("fr");
// "2 901 234 564"
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.tolocalestring |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.prototype.toString()`
Object.getOwnPropertyDescriptor()
=================================

**`Object.getOwnPropertyDescriptor()`** 静态方法返回一个对象，该对象描述给定对象上特定属性（即直接存在于对象上而不在对象的原型链中的属性）的配置。返回的对象是可变的，但对其进行更改不会影响原始属性的配置。

尝试一下
----

语法
--


```js
Object.getOwnPropertyDescriptor(obj, prop)
```

### 参数

`obj`

要查找其属性的对象。

`prop`

要检索其描述的属性的名称或 `Symbol`。

### 返回值

如果指定的属性存在于对象上，则返回其属性描述符，否则返回 `undefined`。

描述
--

该方法允许查看属性的精确描述。在 JavaScript 中，一个*属性*由一个字符串值的名称或一个 `Symbol` 和一个属性描述符组成。关于属性描述符类型及其特性的更多信息可以在 `Object.defineProperty()` 中找到。

一个*属性描述符*是一个记录，具有以下一些特性：

`value`

与属性关联的值（仅限数据描述符）。

`writable`

当且仅当与属性关联的值可以更改时，为 `true`（仅限数据描述符）。

`get`

作为属性 getter 的函数，如果没有 getter 则为 `undefined`（仅限访问器描述符）。

`set`

作为属性 setter 的函数，如果没有 setter 则为 `undefined`（仅限访问器描述符）。

`configurable`

当且仅当此属性描述符的类型可以更改且该属性可以从相应对象中删除时，为 `true`。

`enumerable`

当且仅当此属性在相应对象的属性枚举中出现时，为 `true`。

示例
--

### 使用 Object.getOwnPropertyDescriptor()


```js
let o, d;

o = {
  get foo() {
    return 17;
  },
};
d = Object.getOwnPropertyDescriptor(o, "foo");
console.log(d);
// {
// configurable: true,
// enumerable: true,
// get: [Function: get foo],
// set: undefined
// }

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
console.log(d);
// {
// configurable: true,
// enumerable: true,
// value: 42,
// writable: true
// }

o = { [Symbol.for("baz")]: 73 };
d = Object.getOwnPropertyDescriptor(o, Symbol.for("baz"));
console.log(d);
// {
// configurable: true,
// enumerable: true,
// value: 73,
// writable: true
// }

o = {};
Object.defineProperty(o, "qux", {
  value: 8675309,
  writable: false,
  enumerable: false,
});
d = Object.getOwnPropertyDescriptor(o, "qux");
console.log(d);
// {
// value: 8675309,
// writable: false,
// enumerable: false,
// configurable: false
// }
```

非对象强制转换
-------

在 ES5 中，如果该方法的第一个参数不是对象（而是一个基本类型值），则会导致 `TypeError`。在 ES2015 中，首先会将非对象的第一个参数强制转换为对象。


```js
Object.getOwnPropertyDescriptor("foo", 0);
// TypeError: "foo" is not an object // ES5 code

Object.getOwnPropertyDescriptor("foo", 0);
// Object returned by ES2015 code: {
// configurable: false,
// enumerable: true,
// value: "f",
// writable: false
// }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.getownpropertydescriptor |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.defineProperty()`
* `Reflect.getOwnPropertyDescriptor()`
Object.hasOwn()
===============

如果指定的对象*自身*有指定的属性，则静态方法 **`Object.hasOwn()`** 返回 `true`。如果属性是继承的或者不存在，该方法返回 `false`。

**备注：** `Object.hasOwn()` 旨在取代 `Object.prototype.hasOwnProperty()`。

尝试一下
----

语法
--


```js
Object.hasOwn(obj, prop)
```

### 参数

`obj`

要测试的 JavaScript 实例对象。

`prop`

要测试属性的 `String` 类型的名称或者 Symbol。

### 返回值

如果指定的对象中直接定义了指定的属性，则返回 `true`；否则返回 `false`。

描述
--

如果指定的属性是该对象的直接属性——**`Object.hasOwn()`** 方法返回 `true`，即使属性值是 `null` 或 `undefined`。如果属性是继承的或者不存在，该方法返回 `false`。它不像 `in` 运算符，这个方法不检查对象的原型链中的指定属性。

建议使用此方法替代 `Object.prototype.hasOwnProperty()`，因为它适用于使用 `Object.create(null)` 创建的对象，以及重写了继承的 `hasOwnProperty()` 方法的对象。尽管可以通过在外部对象上调用 `Object.prototype.hasOwnProperty()` 解决这些问题，但是 `Object.hasOwn()` 更加直观。

示例
--

### 使用 hasOwn 去测试属性是否存在

以下代码展示了如何确定 `example` 对象中是否包含名为 `prop` 的属性。


```js
const example = {};
Object.hasOwn(example, "prop"); // false——目标对象的属性 'prop' 未被定义

example.prop = "exists";
Object.hasOwn(example, "prop"); // true——目标对象的属性 'prop' 已被定义

example.prop = null;
Object.hasOwn(example, "prop"); // true——目标对象本身的属性存在，值为 null

example.prop = undefined;
Object.hasOwn(example, "prop"); // true——目标对象本身的属性存在，值为 undefined
```

### 直接属性和继承属性

以下示例区分了直接属性和通过原型链继承的属性：


```js
const example = {};
example.prop = "exists";

// `hasOwn` 静态方法只会对目标对象的直接属性返回 true：
Object.hasOwn(example, "prop"); // 返回 true
Object.hasOwn(example, "toString"); // 返回 false
Object.hasOwn(example, "hasOwnProperty"); // 返回 false

// `in` 运算符对目标对象的直接属性或继承属性均会返回 true：
"prop" in example; // 返回 true
"toString" in example; // 返回 true
"hasOwnProperty" in example; // 返回 true
```

### 迭代对象的属性

要迭代对象的可枚举属性，你*应该*这样使用：


```js
const example = { foo: true, bar: true };
for (const name of Object.keys(example)) {
  // …
}
```


但是如果你使用 `for...in`，你应该使用 `Object.hasOwn()` 跳过继承属性：


```js
const example = { foo: true, bar: true };
for (const name in example) {
  if (Object.hasOwn(example, name)) {
    // …
  }
}
```

### 检查数组索引是否存在

`Array` 中的元素被定义为直接属性，所以你可以使用 `hasOwn()` 方法去检查一个指定的索引是否存在：


```js
const fruits = ["Apple", "Banana", "Watermelon", "Orange"];
Object.hasOwn(fruits, 3); // true ('Orange')
Object.hasOwn(fruits, 4); // false——没有定义的
```

### hasOwnProperty 的问题案例

本部分证明了影响 `hasOwnProperty` 的问题对 `hasOwn()` 是免疫的。首先，它可以与重新实现的 `hasOwnProperty()` 一起使用：


```js
const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: "The dragons be out of office",
};

if (Object.hasOwn(foo, "bar")) {
  console.log(foo.bar); //true——重新实现 hasOwnProperty() 不会影响 Object
}
```


它也可以用于测试使用 `Object.create(null)` 创建的对象。这些对象不会继承自 `Object.prototype`，因此 `hasOwnProperty()` 方法是无法访问的。


```js
const foo = Object.create(null);
foo.prop = "exists";
if (Object.hasOwn(foo, "prop")) {
  console.log(foo.prop); //true——无论对象是如何创建的，它都可以运行。
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.hasown |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* 在 `core-js` 中 `Object.hasOwn` 的 Polyfill
* `Object.hasOwnProperty()`
* 属性的可枚举性和所有权
* `Object.getOwnPropertyNames()`
* `for...in`
* `in`
* JavaScript 指南：重新审视继承
Object.prototype.isPrototypeOf()
================================

**`isPrototypeOf()`** 方法用于检查一个对象是否存在于另一个对象的原型链中。

**备注：** `isPrototypeOf()` 与 `instanceof` 运算符不同。在表达式 `object instanceof AFunction` 中，会检查 `object` 的原型链是否与 `AFunction.prototype` 匹配，而不是与 `AFunction`本身匹配。

尝试一下
----

语法
--


```js
isPrototypeOf(object)
```

### 参数

`object`

要搜索其原型链的对象。

### 返回值

一个布尔值，指示调用 `isPrototypeOf()` 方法的对象（即 `this`）是否位于 `object` 的原型链中。当 `object` 不是一个对象（即基本类型）时，直接返回 `false`。

### 报错

`TypeError`

如果 `prototypeObj` 为 undefined 或 null，会抛出 `TypeError`。

描述
--

所有继承自 `Object.prototype` 的对象（即除了 `null` 原型对象之外的所有对象）都继承了 `isPrototypeOf()` 方法。该方法允许你检查对象是否存在于另一个对象的原型链中。如果作为参数的 `object` 不是对象（即基本类型），则该方法直接返回 `false`。否则，`this` 值被转换为对象，并且在 `object` 的原型链中搜索 `this` 值，直到到达链的末端或找到 `this` 值为止。

示例
--

### 使用 isPrototypeOf()

本示例展示了 `Baz.prototype`、`Bar.prototype`、`Foo.prototype` 和 `Object.prototype` 存在于对象 `baz` 的原型链中：


```js
class Foo {}
class Bar extends Foo {}
class Baz extends Bar {}

const foo = new Foo();
const bar = new Bar();
const baz = new Baz();

// 原型链：
// foo: Foo --> Object
// bar: Bar --> Foo --> Object
// baz: Baz --> Bar --> Foo --> Object
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Baz.prototype.isPrototypeOf(bar)); // false
console.log(Baz.prototype.isPrototypeOf(foo)); // false
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(foo)); // false
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(bar)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
```


`isPrototypeOf()` 方法以及 `instanceof` 运算符在处理从特定原型链继承的对象时非常有用，例如，为了保证该对象上存在特定的方法或属性。

例如，如果只有当 `baz` 对象的原型链中包含 `Foo.prototype` 时才能执行某些代码，可以这样实现：


```js
if (Foo.prototype.isPrototypeOf(baz)) {
  // 执行安全操作
}
```


然而，`Foo.prototype` 存在于 `baz` 的原型链中并不意味着 `baz` 是使用 `Foo` 作为其构造函数创建的。例如，`baz` 可以直接将 `Foo.prototype` 作为其原型。在这种情况下，如果你的代码从 `baz` 中读取 `Foo` 的私有属性，它仍然会失败：


```js
class Foo {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
}

const baz = { \_\_proto\_\_: Foo.prototype };

if (Foo.prototype.isPrototypeOf(baz)) {
  console.log(Foo.getValue(baz)); // TypeError: Cannot read private member #value from an object whose class did not declare it
}
```


对于 `instanceof` 也是同样的情况。如果你需要以安全的方式读取私有属性，可以提供一个使用 `in` 运算符的特定类型检查（branded check）方法。


```js
class Foo {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
  static isFoo(x) {
    return #value in x;
  }
}

const baz = { \_\_proto\_\_: Foo.prototype };

if (Foo.isFoo(baz)) {
  // 不会运行，因为 baz 不是 Foo
  console.log(Foo.getValue(baz));
}
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.isprototypeof |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `instanceof`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()`
* 继承与原型链
Object.isSealed()
=================

**`Object.isSealed()`** 静态方法判断一个对象是否被密封。

尝试一下
----

语法
--


```js
Object.isSealed(obj)
```

### 参数

`obj`

要被检查的对象。

### 返回值

一个表示给定对象是否被密封的布尔值。

描述
--

如果这个对象是密封的，则返回 `true`，否则返回 `false`。密封对象是指那些不可扩展的，且所有自有属性都不可配置且因此不可删除（但不一定是不可写）的对象。

示例
--

### 使用 Object.isSealed()


```js
// 新建的对象默认不是密封的。
const empty = {};
Object.isSealed(empty); // false

// 如果你令一个空对象不可扩展，则它同时也会变成个密封对象。
Object.preventExtensions(empty);
Object.isSealed(empty); // true

// 但如果这个对象不是空对象，则它不会变成密封对象，因为密封对象的所有自身属性必须是不可配置的。
const hasProp = { fee: "fie foe fum" };
Object.preventExtensions(hasProp);
Object.isSealed(hasProp); // false

// 如果把这个属性变的不可配置，则这个属性也就成了密封对象。
Object.defineProperty(hasProp, "fee", {
  configurable: false,
});
Object.isSealed(hasProp); // true

// 密封一个对象最简单的方法当然是 Object.seal。
const sealed = {};
Object.seal(sealed);
Object.isSealed(sealed); // true

// 根据定义，密封对象是不可扩展的。
Object.isExtensible(sealed); // false

// 一个密封对象可能被冻结，但不一定。
Object.isFrozen(sealed); // true
//（所有属性也是不可写的）

const s2 = Object.seal({ p: 3 });
Object.isFrozen(s2); // false
//（'p' 仍然可写）

const s3 = Object.seal({
  get p() {
    return 0;
  },
});
Object.isFrozen(s3); // true
//（对于访问器属性，只有可配置性才有影响）
```

非对象参数
-----

在 ES5 中，如果该方法的参数不是一个对象（而是一个基本类型值），则会引发 `TypeError` 异常。在 ES2015 中，如果传递一个非对象参数，则该方法将返回 `true` 而不会产生任何错误，因为按照定义，基本类型值是不可变的。


```js
Object.isSealed(1);
// TypeError: 1 is not an object (ES5 code)

Object.isSealed(1);
// true (ES2015 code)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.issealed |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.seal()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`
Object.prototype.\_\_lookupSetter\_\_()
=======================================

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

**备注：** 该方法已被弃用，建议使用 `Object.getOwnPropertyDescriptor()` API。该方法的行为只针对 Web 兼容性进行了规定，在任何平台上都不需要实现该方法。它可能无法在所有地方正常工作。

**`__lookupGetter__()`** 方法返回绑定到指定属性的 setter 函数。

语法
--


```js
\_\_lookupSetter\_\_(prop)
```

### 参数

`prop`

包含应返回其 setter 的属性名称的字符串。

### 返回值

绑定到指定属性的 setter 函数。如果找不到这样的属性或者该属性是数据属性，则返回 `undefined`。

描述
--

所有继承自 `Object.prototype` 的对象（也就是除了 `null` 原型对象的对象）都会继承 `__lookupSetter__()` 方法。如果为对象的属性定义了一个 setter，则无法通过该属性引用 setter 函数，因为该属性引用该函数的返回值。`__lookupSetter__()` 可用于获取对 setter 函数的引用。

`__lookupSetter__()` 沿着原型链向上查找指定的属性。如果原型链上的任何对象具有指定的自有属性，则返回该属性的属性描述符的 `set` 属性。如果该属性是数据属性，则返回 `undefined`。如果在整个原型链上都找不到该属性，也同样返回 `undefined`。

`__lookupSetter__()` 在规范中被定义为“可选规范”，这意味着不需要任何实现来实现它。然而，所有主要的浏览器都实现了它，并且由于它的持续使用，它不太可能被删除。如果浏览器实现了 `__lookupSetter__()`，它还需要实现 `__lookupGetter__()`、`__defineGetter__()` 和 `__defineSetter__()` 方法。

示例
--

### 使用 \_\_lookupSetter\_\_()


```js
const obj = {
  set foo(value) {
    this.bar = value;
  },
};

obj.\_\_lookupSetter\_\_("foo");
// [Function: set foo]
```

### 以标准方式查找属性的 setter

你应该使用 `Object.getOwnPropertyDescriptor()` API 来查找属性的 setter。与 `__lookupSetter__()` 相比，该方法允许查找 Symbol 属性。`Object.getOwnPropertyDescriptor()` 方法还适用于 `null` 原型对象，它们不继承自 `Object.prototype`，因此没有 `__lookupSetter__()` 方法。如果 `__lookupSetter__()` 沿着原型链向上查找属性的行为很重要，则可以使用 `Object.getPrototypeOf()` 自行实现它。


```js
const obj = {
  set foo(value) {
    this.bar = value;
  },
};

Object.getOwnPropertyDescriptor(obj, "foo").set;
// [Function: set foo]
```



```js
const obj2 = {
  \_\_proto\_\_: {
    set foo(value) {
      this.bar = value;
    },
  },
};

function findSetter(obj, prop) {
  while (obj) {
    const desc = Object.getOwnPropertyDescriptor(obj, "foo");
    if (desc) {
      return desc.set;
    }
    obj = Object.getPrototypeOf(obj);
  }
}

console.log(findSetter(obj2, "foo")); // [Function: set foo]
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_lookupSetter\_\_ |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Object.prototype.__lookupSetter__` 的 polyfill
* `Object.prototype.__lookupGetter__()`
* `set` 语法
* `Object.getOwnPropertyDescriptor()` 和 `Object.getPrototypeOf()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* JS 指南：定义 Getter 和 Setter
Object.seal()
=============

**`Object.seal()`** 静态方法*密封*一个对象。密封一个对象会阻止其扩展并且使得现有属性不可配置。密封对象有一组固定的属性：不能添加新属性、不能删除现有属性或更改其可枚举性和可配置性、不能重新分配其原型。只要现有属性的值是可写的，它们仍然可以更改。`seal()` 返回传入的同一对象。

尝试一下
----

语法
--


```js
Object.seal(obj)
```

### 参数

`obj`

要密封的对象。

### 返回值

被密封的对象。

描述
--

密封一个对象等价于阻止其扩展，然后将现有的属性描述符更改为 `configurable: false`。这会使对象上的属性集固定。令对象的所有属性不可配置且可以防止它们从数据属性转换成访问器属性，反之亦然，但它不会防止数据属性的值被更改。尝试删除或者向密封对象添加属性，或者将数据属性和访问器属性互相转换，都将失败，可能会静默失败，也可能会抛出 `TypeError`（最常见的是在严格模式代码中，但不仅限于此）。

原型链保持不变。然而，由于扩展被阻止，`[[Prototype]]` 不能重新赋值。

不同于 `Object.freeze()` 的是，通过 `Object.seal()` 密封的对象可以更改其现有属性，只要它们是可写的。

示例
--

### 使用 Object.seal()


```js
const obj = {
  prop() {},
  foo: "bar",
};

// 可以添加新属性，可以更改或删除现有属性。
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;

const o = Object.seal(obj);

o === obj; // true
Object.isSealed(obj); // true

// 更改密封对象的属性值仍然有效。
obj.foo = "quux";

// 但不能将数据属性转换成访问者属性，反之亦然。
Object.defineProperty(obj, "foo", {
  get() {
    return "g";
  },
}); // 抛出 TypeError

// 现在，除了属性值之外的任何更改都将失败。
obj.quaxxor = "the friendly duck";
// 静默不添加属性
delete obj.foo;
// 静默不添删除属性

// ...且严格模式下，这种尝试将会抛出 TypeError。
function fail() {
  "use strict";
  delete obj.foo; // 抛出一个 TypeError
  obj.sparky = "arf"; // 抛出一个 TypeError
}
fail();

// 尝试通过 Object.defineProperty 添加属性也会抛出错误。
Object.defineProperty(obj, "ohai", {
  value: 17,
}); // 抛出 TypeError
Object.defineProperty(obj, "foo", {
  value: "eit",
}); // 更改现有属性值
```

### 非对象参数

在 ES5 中，如果该方法的参数不是一个对象（即基本类型），它将会抛出 `TypeError`。在 ES2015 中，非对象参数将按原样返回，不会有任何错误，因为根据定义，基本类型已经是不可变的。


```js
Object.seal(1);
// TypeError: 1 is not an object (ES5 code)

Object.seal(1);
// 1 (ES2015 code)
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.seal |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.isSealed()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.freeze()`
* `Object.isFrozen()`
Object.isFrozen()
=================

**`Object.isFrozen()`** 静态方法判断一个对象是否被冻结。

尝试一下
----

语法
--


```js
Object.isFrozen(obj)
```

### 参数

`obj`

要检测的对象。

### 返回值

指示给定对象是否被冻结的布尔值。

描述
--

一个对象，当且仅当它不可拓展，且所有属性都是不可配置的，所有的数据属性（即不是有 getter 或 setter 的访问器属性的属性）都是不可写的时，它就是被冻结的。

示例
--

### 使用 Object.isFrozen()


```js
// 一个新对象是默认是可扩展的，所以它也是非冻结的。
Object.isFrozen({}); // false

// 一个不可扩展的空对象同时也是一个冻结对象。
const vacuouslyFrozen = Object.preventExtensions({});
Object.isFrozen(vacuouslyFrozen); // true

// 一个非空对象默认也是非冻结的。
const oneProp = { p: 42 };
Object.isFrozen(oneProp); // false

// 即使令对象不可扩展，它也不会被冻结，因为属性仍然是可配置的（而且可写的）。
Object.preventExtensions(oneProp);
Object.isFrozen(oneProp); // false

// 此时，如果删除了这个属性，则它会成为一个冻结对象。
delete oneProp.p;
Object.isFrozen(oneProp); // true

// 一个不可扩展的对象，拥有一个不可写但可配置的属性，则它仍然是非冻结的。
const nonWritable = { e: "plep" };
Object.preventExtensions(nonWritable);
Object.defineProperty(nonWritable, "e", {
  writable: false,
}); // 令其不可写
Object.isFrozen(nonWritable); // false

// 把这个属性改为不可配置，会让这个对象成为冻结对象。
Object.defineProperty(nonWritable, "e", {
  configurable: false,
}); // 令其不可配置
Object.isFrozen(nonWritable); // true

// 一个不可扩展的对象，拥有一个不可配置但可写的属性，则它也是非冻结的。
const nonConfigurable = { release: "the kraken!" };
Object.preventExtensions(nonConfigurable);
Object.defineProperty(nonConfigurable, "release", {
  configurable: false,
});
Object.isFrozen(nonConfigurable); // false

// 把这个属性改为不可写，会让这个对象成为冻结对象。
Object.defineProperty(nonConfigurable, "release", {
  writable: false,
});
Object.isFrozen(nonConfigurable); // true

// 一个不可扩展的对象，拥有一个访问器属性，则它仍然是非冻结的。
const accessor = {
  get food() {
    return "yum";
  },
};
Object.preventExtensions(accessor);
Object.isFrozen(accessor); // false

// 把这个属性改为不可配置，会让这个对象成为冻结对象。
Object.defineProperty(accessor, "food", {
  configurable: false,
});
Object.isFrozen(accessor); // true

// 使用 Object.freeze 是冻结一个对象最方便的方法。
const frozen = { 1: 81 };
Object.isFrozen(frozen); // false
Object.freeze(frozen);
Object.isFrozen(frozen); // true

// 根据定义，一个冻结对象是不可拓展的。
Object.isExtensible(frozen); // false

// 同样，根据定义，一个冻结对象也是密封对象。
Object.isSealed(frozen); // true
```

### 非对象参数

在 ES5 中，如果传递给此方法的参数不是一个对象（而是一个基本类型值），则会导致 `TypeError`。在 ES2015 中，如果传递了一个非对象类型的参数，它将返回 `true` 而不会出现错误，因为基本类型值在定义上是不可变的。


```js
Object.isFrozen(1);
// TypeError: 1 is not an object（ES5 代码）

Object.isFrozen(1);
// true （ES2015 代码）
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.isfrozen |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `Object.freeze()`
* `Object.preventExtensions()`
* `Object.isExtensible()`
* `Object.seal()`
* `Object.isSealed()`
Object.fromEntries()
====================

**`Object.fromEntries()`** 静态方法将键值对列表转换为一个对象。

尝试一下
----

语法
--


```js
Object.fromEntries(iterable)
```

### 参数

`iterable`

一个包含对象列表的可迭代对象，例如 `Array` 或者 `Map`。每个对象都要有两个属性：

`0`

表示属性键的字符串或者 Symbol。

`1`

属性值。

通常，该对象被实现为二元数组，第一个元素是属性键，第二个元素是属性值。

### 返回值

一个新对象，其属性由可迭代对象的条目给定。

描述
--

`Object.fromEntries()` 方法接收一个键值对列表，并返回一个新对象，该对象的属性由这些条目给定。`iterable` 参数应该是实现了 `@@iterator` 方法的可迭代对象。该方法返回一个可迭代对象，产生包含两个元素的类数组对象。第一个元素是将用作属性键的值，第二个元素是要与该属性键关联的值。

`Object.fromEntries()` 是 `Object.entries()` 的逆操作，只是 `Object.entries()` 只返回字符串键属性，而 `Object.fromEntries()` 还可以创建符号键属性。

**备注：** 与 `Array.from()` 不同的是，`Object.fromEntries()` 不使用 `this` 的值，因此在另一个构造函数上调用它不会创建该类型的对象。

示例
--

### 将 Map 转换成对象

通过 `Object.fromEntries`，你可以将 `Map` 转换成 `Object`：


```js
const map = new Map([
  ["foo", "bar"],
  ["baz", 42],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
```

### 将 Array 转换成对象

通过 `Object.fromEntries`，你可以将 `Array` 转换成 `Object`：


```js
const arr = [
  ["0", "a"],
  ["1", "b"],
  ["2", "c"],
];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
```

### 对象转换

通过 `Object.fromEntries`、其逆操作 `Object.entries()` 和数组操作方法，你可以像这样转换对象：


```js
const object1 = { a: 1, b: 2, c: 3 };

const object2 = Object.fromEntries(
  Object.entries(object1).map(([key, val]) => [key, val \* 2]),
);

console.log(object2);
// { a: 2, b: 4, c: 6 }
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.fromentries |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Object.fromEntries` 的 Polyfill
* `Object.entries()`
* `Object.keys()`
* `Object.values()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Map.prototype.entries()`
* `Map.prototype.keys()`
* `Map.prototype.values()`
Object.values()
===============

**`Object.values()`** 静态方法返回一个给定对象的自有可枚举字符串键属性值组成的数组。

尝试一下
----

语法
--


```js
Object.values(obj)
```

### 参数

`obj`

一个对象。

### 返回值

一个包含了给定对象的自有可枚举字符串键属性值的数组。

描述
--

`Object.values()` 返回一个数组，其元素是直接在 `object` 上找到的可枚举字符串键属性值。这与使用 `for...in` 循环迭代相同，只是 `for...in` 循环还枚举原型链中的属性。`Object.values()` 返回的数组顺序和 `for...in` 循环提供的数组顺序相同。

如果需要属性键，请使用 `Object.keys()`。如果属性的键和值都需要，请使用 `Object.entries()`。

示例
--

### 使用 Object.values()


```js
const obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// 类数组对象
const arrayLikeObj1 = { 0: "a", 1: "b", 2: "c" };
console.log(Object.values(arrayLikeObj1)); // ['a', 'b', 'c']

// 具有随机键排序的类数组对象
// 使用数字键时，将按键的数字顺序返回值
const arrayLikeObj2 = { 100: "a", 2: "b", 7: "c" };
console.log(Object.values(arrayLikeObj2)); // ['b', 'c', 'a']

// getFoo 是一个不可枚举的属性
const myObj = Object.create(
  {},
  {
    getFoo: {
      value() {
        return this.foo;
      },
    },
  },
);
myObj.foo = "bar";
console.log(Object.values(myObj)); // ['bar']
```

### 在基本类型中使用 Object.values()

非对象参数会强制转换为对象。`undefined` 和 `null` 不能被强制转换为对象，会立即抛出 `TypeError`。只有字符串可以有自己的可枚举属性，而其他所有基本类型都返回一个空数组。


```js
// 字符串具有索引作为可枚举的自有属性
console.log(Object.values("foo")); // ['f', 'o', 'o']

// 其他基本类型（除了 undefined 和 null）没有自有属性
console.log(Object.values(100)); // []
```

规范
--

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.values |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `core-js` 中 `Object.values` 的 Polyfill
* 属性的可枚举性和所有权
* `Object.keys()`
* `Object.entries()`
* `Object.prototype.propertyIsEnumerable()`
* `Object.create()`
* `Object.getOwnPropertyNames()`
* `Map.prototype.values()`