aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/operators/property_accessors/index.html
blob: 6d139479f9e8501c6a1a139889cd22360ec6268d (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
---
title: 属性访问器
slug: Web/JavaScript/Reference/Operators/Property_Accessors
tags:
  - JavaScript
  - Operator
  - 操作符
translation_of: Web/JavaScript/Reference/Operators/Property_Accessors
---
<div>{{jsSidebar("Operators")}}</div>

<p>属性访问器提供了两种方式用于访问一个对象的属性,它们分别是点号和方括号。</p>

<div>{{EmbedInteractiveExample("pages/js/expressions-propertyaccessors.html")}}</div>



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

<pre class="syntaxbox">object.property
object['property']
</pre>

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

<p>我们可以将对象看做是一个<em>关联数组(</em>或者:<em>映射</em><em>字典</em><em>哈希表</em><em>查询表</em>)。这个数组中的键就是这个对象中属性的名称。通常,当我们提及一个对象的属性时,会对属性与方法之间做个对比。然而,属性与方法之间的区别并不大。一个方法就是一个可以被调用的属性而已,例如一个指向函数 <a href="/zh-CN/docs/Glossary/Function">Function</a> 实例的引用可以作为对象属性的值。</p>

<p>访问对象属性有两种方式:点号表示法和方括号表示法。</p>

<h3 id="点号表示法">点号表示法</h3>

<pre class="brush: js">get = object.property;
object.property = set;
</pre>

<p>以上代码中,<code>property</code>必须是一个有效的 JavaScript 标识符,例如,一串字母数字字符,也包括下划线及美元符号,但不能以数字作为开头。比如,<code>object.$1</code>是合法的,而 <code>object.1</code>是无效不合法的。</p>

<pre class="brush: js">document.createElement('pre');
</pre>

<p>在上述代码块中,<code>document</code>中存在一个名为"createElement"的方法并且被调用了。</p>

<p>如果对数字字面量使用方法,并且数字文字没有指数且没有小数点,请在方法调用之前的点之前留出空格,以防止点被解释为小数点。</p>

<pre class="brush: js">77 .toExponential();
// 或
77
.toExponential();
// 或
(77).toExponential();
// 或
77..toExponential();
// 或
77.0.toExponential();
// 因为 77. === 77.0,没有歧义(no ambiguity)
</pre>

<h3 id="方括号表示法">方括号表示法</h3>

<pre class="brush: js">get = object[property_name];
object[property_name] = set;
</pre>

<p><code>property_name</code> 是一个字符串。该字符串不一定是一个合法的标识符;它可以是任意值,例如,"1foo","!bar!",甚至是 " "(一个空格)。</p>

<pre class="brush: js">document['createElement']('pre');
</pre>

<p>这里的代码的功能跟上一个例子的作用是相同的。</p>

<p>括号之前允许有空格。</p>

<pre class="brush: js">document ['createElement']('pre');
</pre>

<h3 id="属性名称">属性名称</h3>

<p>属性名称必须是字符串或符号 Symbol。这意味着非字符串对象不能用来作为一个对象属性的键。任何非字符串对象,包括 Number,都会通过 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString">toString</a> 方法,被转换成一个字符串。</p>

<pre class="brush: js">var object = {};
object['1'] = 'value';
console.log(object[1]);
</pre>

<p>上述代码的输出为"value",因为 1 被类型转换为'1'。</p>

<pre class="brush: js">var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
object[foo] = 'value';
console.log(object[bar]);
</pre>

<p>上述的代码的输出也是 "value",由于对象 foo 和 bar 都会被转成相同的字符串。在<a href="/zh-CN/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> JavaScript 引擎中,这个字符串是 "[object Object]"。</p>

<h3 id="方法绑定">方法绑定</h3>

<p>一个方法没有绑定到对象上,那就意味着这个方法是不起作用的。特别要注意的是,在一个方法中<code>this</code>对象并不是固定的,例如,<code>this</code>不需要指向包含当前方法的对象。<code>this</code>可通过函数调用被传递过去的值所替换。详见<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/this#Method_binding">方法绑定</a></p>

<h3 id="注意eval">注意<code>eval</code></h3>

<p>在那些可通过方括号表示法替换的场景下,JavaScript 新手在使用<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval">eval</a> 经常会犯错。例如,下面的语法经常在很多代码中找到。</p>

<pre class="brush: js">x = eval('document.forms.form_name.elements.' + strFormControl + '.value');
</pre>

<p><a href="https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/"><code>eval</code></a> 的性能较差,且有安全风险。在任何时候都应该避免使用。而且,此时 <code>strFormControl</code> 必须是一个合法的标识符, 这在一些表单控件的 name、ID 值之中并不是必要的。所以,使用括号来代替会更好一些:</p>

<pre class="brush: js">x = document.forms["form_name"].elements[strFormControl].value;
</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范</th>
   <th scope="col">状态</th>
   <th scope="col">备注</th>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-property-accessors', 'Property Accessors')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-property-accessors', 'Property Accessors')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-11.2.1', 'Property Accessors')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES1', '#sec-11.2.1', 'Property Accessors')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.0.</td>
  </tr>
 </tbody>
</table>

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

<p>{{Compat("javascript.operators.property_accessors")}}</p>

<h2 id="参见">参见</h2>

<ul>
 <li>{{jsxref("Object")}}</li>
 <li>{{jsxref("Object/defineProperty")}}</li>
</ul>