aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/object/defineproperties/index.html
blob: 411650ccb85e4bd794f831d3fd0367dbb5d52703 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
---
title: Object.defineProperties()
slug: Web/JavaScript/Reference/Global_Objects/Object/defineProperties
tags:
  - ECMAScript 5
  - JavaScript
  - Method
  - Object
translation_of: Web/JavaScript/Reference/Global_Objects/Object/defineProperties
---
<p>{{JSRef}}</p>

<p><strong><code>Object.defineProperties()</code> </strong>方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。</p>

<h2 id="Syntax" name="Syntax">语法</h2>

<pre class="notranslate"><code>Object.defineProperties(<var>obj</var><var>props</var>)</code></pre>

<h3 id="Parameters" name="Parameters">参数</h3>

<dl>
 <dt><code>obj</code></dt>
 <dd>在其上定义或修改属性的对象。</dd>
 <dt><code>props</code></dt>
 <dd>要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符(更多详情,请参阅{{jsxref("Object.defineProperty()")}})。描述符具有以下键:</dd>
 <dd>
 <dl>
  <dt><code>configurable</code></dt>
  <dd><code>true</code> 只有该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。<br>
  <strong>默认为 <code>false</code></strong></dd>
  <dt><code>enumerable</code></dt>
  <dd><code>true</code> 只有在枚举相应对象上的属性时该属性显现。<br>
  <strong>默认为 <code>false</code></strong></dd>
 </dl>

 <dl>
  <dt><code>value</code></dt>
  <dd>与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。<br>
  <strong>默认为 {{jsxref("undefined")}}.</strong></dd>
  <dt><code>writable</code></dt>
  <dd><code>true</code>只有与该属性相关联的值被{{jsxref("Operators/Assignment_Operators", "assignment operator", "", 1)}}改变时。<br>
  <strong>默认为 <code>false</code></strong></dd>
 </dl>

 <dl>
  <dt><code>get</code></dt>
  <dd>作为该属性的 getter 函数,如果没有 getter 则为{{jsxref("undefined")}}。函数返回值将被用作属性的值。<br>
  <strong>默认为 {{jsxref("undefined")}}</strong></dd>
  <dt><code>set</code></dt>
  <dd>作为属性的 setter 函数,如果没有 setter 则为{{jsxref("undefined")}}。函数将仅接受参数赋值给该属性的新值。<br>
  <strong>默认为 {{jsxref("undefined")}}</strong></dd>
 </dl>
 </dd>
</dl>

<h3 id="返回值">返回值</h3>

<p>传递给函数的对象。</p>

<h2 id="描述">描述</h2>

<p><code>Object.defineProperties</code>本质上定义了<code>obj</code> 对象上<code>props</code>的可枚举属性相对应的所有属性。</p>

<h2 id="例子">例子</h2>

<pre class="brush: js notranslate">var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});</pre>

<h2 id="Polyfill">Polyfill</h2>

<p>假设一个原始的执行环境,所有的名称和属性都引用它们的初始值,<code>Object.defineProperties</code>几乎完全等同于(注意<code>isCallable</code>中的注释)以下JavaScript中的重新实现:</p>

<pre class="brush: js notranslate">function defineProperties(obj, properties) {
  function convertToDescriptor(desc) {
    function hasProperty(obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    }

    function isCallable(v) {
      // NB: modify as necessary if other values than functions are callable.
      return typeof v === 'function';
    }

    if (typeof desc !== 'object' || desc === null)
      throw new TypeError('bad desc');

    var d = {};

    if (hasProperty(desc, 'enumerable'))
      d.enumerable = !!desc.enumerable;
    if (hasProperty(desc, 'configurable'))
      d.configurable = !!desc.configurable;
    if (hasProperty(desc, 'value'))
      d.value = desc.value;
    if (hasProperty(desc, 'writable'))
      d.writable = !!desc.writable;
    if (hasProperty(desc, 'get')) {
      var g = desc.get;

      if (!isCallable(g) &amp;&amp; typeof g !== 'undefined')
        throw new TypeError('bad get');
      d.get = g;
    }
    if (hasProperty(desc, 'set')) {
      var s = desc.set;
      if (!isCallable(s) &amp;&amp; typeof s !== 'undefined')
        throw new TypeError('bad set');
      d.set = s;
    }

    if (('get' in d || 'set' in d) &amp;&amp; ('value' in d || 'writable' in d))
      throw new TypeError('identity-confused descriptor');

    return d;
  }

  if (typeof obj !== 'object' || obj === null)
    throw new TypeError('bad obj');

  properties = Object(properties);

  var keys = Object.keys(properties);
  var descs = [];

  for (var i = 0; i &lt; keys.length; i++)
    descs.push([keys[i], convertToDescriptor(properties[keys[i]])]);

  for (var i = 0; i &lt; descs.length; i++)
    Object.defineProperty(obj, descs[i][0], descs[i][1]);

  return obj;
}</pre>

<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.2.3.7', 'Object.defineProperties')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.8.5</td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-object.defineproperties', 'Object.defineProperties')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-object.defineproperties', 'Object.defineProperties')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<div class="hidden">The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div>

<p>{{Compat("javascript.builtins.Object.defineProperties")}}</p>

<h2 id="See_also" name="See_also">相关链接</h2>

<ul>
 <li>{{jsxref("Object.defineProperty()")}}</li>
 <li>{{jsxref("Object.keys()")}}</li>
 <li><a href="/zh-CN/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">属性的可枚举性和所有权</a></li>
</ul>