aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/operators/new/index.html
blob: 0b2d5c24c7f6664714c6d373586b5e251dfe70b5 (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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
---
title: new 运算符
slug: Web/JavaScript/Reference/Operators/new
tags:
  - JavaScript
  - Left-hand-side expressions
  - Operator
  - 操作符
translation_of: Web/JavaScript/Reference/Operators/new
---
<div>{{jsSidebar("Operators")}}</div>

<p><strong><code>new</code> 运算符</strong>创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。</p>

<ol>
</ol>

<p>{{EmbedInteractiveExample("pages/js/expressions-newoperator.html")}}</p>

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

<pre class="syntaxbox notranslate">new <em>constructor</em>[([<em>arguments</em>])]</pre>

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

<dl>
 <dt><code>constructor</code></dt>
 <dd>一个指定对象实例的类型的类或函数。</dd>
</dl>

<dl>
 <dt><code>arguments</code></dt>
 <dd>一个用于被 <code>constructor</code> 调用的参数列表。</dd>
</dl>

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

<p><strong><code>new</code></strong> 关键字会进行如下的操作:</p>

<ol>
 <li>创建一个空的简单JavaScript对象(即<code><strong>{}</strong></code>);</li>
 <li>为步骤1新创建的对象添加属性<code><strong>__proto__</strong></code>,将该属性链接至构造函数的原型对象 ;</li>
 <li>将步骤1新创建的对象作为<code><strong>this</strong></code>的上下文 ;</li>
 <li>如果该函数没有返回对象,则返回<code><strong>this</strong></code></li>
</ol>

<p>(译注:关于对象的 <code><strong>constructor</strong></code>,参见 <code><strong>Object.prototype.constructor</strong></code></p>

<p>创建一个用户自定义的对象需要两步:</p>

<ol>
 <li>通过编写函数来定义对象类型。</li>
 <li>通过 <code>new</code> 来创建对象实例。</li>
</ol>

<p>创建一个对象类型,需要创建一个指定其名称和属性的函数;对象的属性可以指向其他对象,看下面的例子:</p>

<p>当代码 <code>new <em>Foo</em>(...)</code> 执行时,会发生以下事情:</p>

<ol>
 <li>一个继承自 <code><em>Foo</em>.prototype</code> 的新对象被创建。</li>
 <li>使用指定的参数调用构造函数 <em><code>Foo</code></em>,并将 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/this">this</a></code> 绑定到新创建的对象。<code>new <em>Foo</em></code> 等同于 <em><code>new Foo</code></em><code>()</code>,也就是没有指定参数列表,<em><code>Foo</code></em> 不带任何参数调用的情况。</li>
 <li>由构造函数返回的对象就是 <code>new</code> 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)</li>
</ol>

<p>你始终可以对已定义的对象添加新的属性。例如,<code>car1.color = "black"</code> 语句给 <code>car1</code> 添加了一个新的属性 <code>color</code>,并给这个属性赋值 "<code>black</code>"。但是,这不会影响任何其他对象。要将新属性添加到相同类型的所有对象,你必须将该属性添加到 <code>Car</code> 对象类型的定义中。</p>

<p>你可以使用 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype">Function.prototype</a></code> 属性将共享属性添加到以前定义的对象类型。这定义了一个由该函数创建的所有对象共享的属性,而不仅仅是对象类型的其中一个实例。下面的代码将一个值为 <code>null</code><code>color</code> 属性添加到 <code>car</code> 类型的所有对象,然后仅在实例对象 <code>car1</code> 中用字符串 "<code>black</code>" 覆盖该值。详见 <a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype">prototype</a></p>

<pre class="brush: js notranslate">function Car() {}
car1 = new Car();
car2 = new Car();

console.log(car1.color);    // undefined

Car.prototype.color = "original color";
console.log(car1.color);    // original color

car1.color = 'black';
console.log(car1.color);   // black

console.log(car1.__proto__.color) //original color
console.log(car2.__proto__.color) //original color
console.log(car1.color)  // black
console.log(car2.color) // original color
</pre>

<div class="note">
<p>如果你没有使用 <code>new</code> 运算符, <strong>构造函数会像其他的常规函数一样被调用,</strong><em>不会创建一个对象<strong></strong></em>在这种情况下, <code>this</code> 的指向也是不一样的。</p>
</div>

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

<h3 id="对象类型和对象实例">对象类型和对象实例</h3>

<p>假设你要创建一个汽车的对象类型。你希望这个类型叫做car,这个类型具备make, model, year等属性,要做到这些,你需要写这样一个函数:</p>

<pre class="brush: js notranslate">function Car(make, model, year) {
   this.make = make;
   this.model = model;
   this.year = year;
}
</pre>

<p>现在,你可以如下所示创建一个 <code>mycar</code> 的对象:</p>

<pre class="brush: js notranslate">var mycar = new Car("Eagle", "Talon TSi", 1993);</pre>

<p>这段代码创建了 <code>mycar</code> 并给他的属性指定值,于是 <code>mycar.make</code> 的值为"<code>Eagle</code>", <code>mycar.year</code> 的值为1993,以此类推。</p>

<p>你可以通过调用 <code>new</code> 来创建任意个汽车对象。例如:</p>

<pre class="brush: js notranslate">var kenscar = new Car("Nissan", "300ZX", 1992);</pre>

<h3 id="对象属性为其他对象">对象属性为其他对象</h3>

<p>假设你定义了一个对象叫做 <code>person</code></p>

<pre class="brush: js notranslate">function Person(name, age, sex) {
   this.name = name;
   this.age = age;
   this.sex = sex;
}
</pre>

<p>然后实例化两个新的 <code>person</code> 对象如下:</p>

<pre class="brush: js notranslate">var rand = new Person("Rand McNally", 33, "M");
var ken = new Person("Ken Jones", 39, "M");
</pre>

<p>然后你可以重写 <code>car</code> 的定义,添加一个值为 <code>person</code> 对象的 <code>owner</code> 属性,如下:</p>

<pre class="brush: js notranslate">function Car(make, model, year, owner) {
   this.make = make;
   this.model = model;
   this.year = year;
   this.owner = owner;
}
</pre>

<p>为了实例化新的对象,你可以用如下代码:</p>

<pre class="brush: js notranslate">var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
</pre>

<p>创建对象时,并没有传字符串或数字给owner,而是传了对象 <code>rand</code><code>ken</code> 。这个时候,你可以这样来获取 <code>car2</code> 的owner的name:</p>

<pre class="brush: js notranslate">car2.owner.name</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-new-operator', 'The new Operator')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-new-operator', 'The new Operator')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-11.2.2', 'The new Operator')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES3', '#sec-11.2.2', 'The new Operator')}}</td>
   <td>{{Spec2('ES3')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES1', '#sec-11.2.2', 'The new Operator')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>初始定义。JavaScript 1.0实现。</td>
  </tr>
 </tbody>
</table>

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

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

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

<ul>
 <li>{{jsxref("Function")}}</li>
 <li>{{jsxref("Reflect.construct()")}}</li>
 <li>{{jsxref("Object.prototype")}}</li>
</ul>