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
|
---
title: Function.prototype.call()
slug: Web/JavaScript/Reference/Global_Objects/Function/call
tags:
- JavaScript
- 函数
- 方法
translation_of: Web/JavaScript/Reference/Global_Objects/Function/call
---
<div>{{JSRef}}</div>
<p><code><strong>call()</strong></code> 方法使用一个指定的 <code>this</code> 值和单独给出的一个或多个参数来调用一个函数。</p>
<div class="note"><strong>注意:</strong>该方法的语法和作用与 {{jsxref("Function.apply", "apply()")}} 方法类似,只有一个区别,就是 <code>call()</code> 方法接受的是<strong>一个参数列表</strong>,而 <code>apply()</code> 方法接受的是<strong>一个包含多个参数的数组</strong>。</div>
<div>{{EmbedInteractiveExample("pages/js/function-call.html")}}</div>
<h2 id="语法">语法</h2>
<pre class="syntaxbox"><code><em>function</em>.call(<em>thisArg</em>, <em>arg1</em>, <em>arg2</em>, ...)</code></pre>
<h3 id="参数">参数</h3>
<dl>
<dt><code>thisArg</code></dt>
<dd>可选的。在 <em><code>function</code></em> 函数运行时使用的 <code>this</code> 值。请注意,<code>this</code>可能不是该方法看到的实际值:如果这个函数处于<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode" title="如果你想改变你的代码,让其工作在具有限制性JavaScript环境中,请参阅转换成严格模式。">非严格模式</a>下,则指定为 <code>null</code> 或 <code>undefined</code> 时会自动替换为指向全局对象,原始值会被包装。</dd>
<dt><code>arg1, arg2, ...</code></dt>
<dd>指定的参数列表。</dd>
</dl>
<h2 id="返回值">返回值</h2>
<p>使用调用者提供的 <code>this</code> 值和参数调用该函数的返回值。若该方法没有返回值,则返回 <code>undefined</code>。</p>
<h2 id="描述">描述</h2>
<p><code>call()</code> 允许为不同的对象分配和调用属于一个对象的函数/方法。</p>
<p><code>call()</code> 提供新的 <strong>this </strong>值给当前调用的函数/方法。你可以使用 <code>call</code> 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。</p>
<h2 id="示例">示例</h2>
<h3 id="使用_call_方法调用父构造函数">使用 <code>call</code> 方法调用父构造函数</h3>
<p>在一个子构造函数中,你可以通过调用父构造函数的 <code>call</code> 方法来实现继承,类似于 <code>Java</code> 中的写法。下例中,使用 <code>Food</code> 和 <code>Toy </code>构造函数创建的对象实例都会拥有在 <code>Product</code> 构造函数中添加的 <code>name</code> 属性和 <code>price</code> 属性,但 <code>category</code> 属性是在各自的构造函数中定义的。</p>
<pre class="brush: js">function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
</pre>
<h3 id="使用_call_方法调用匿名函数">使用 <code>call</code> 方法调用匿名函数</h3>
<p>在下例中的 <code>for</code> 循环体内,我们创建了一个匿名函数,然后通过调用该函数的 <code>call</code> 方法,将每个数组元素作为指定的 <code>this</code> 值执行了那个匿名函数。这个匿名函数的主要目的是给每个数组元素对象添加一个 <code>print</code> 方法,这个 <code>print</code> 方法可以打印出各元素在数组中的正确索引号。当然,这里不是必须得让数组元素作为 <code>this</code> 值传入那个匿名函数(普通参数就可以),目的是为了演示 <code>call</code> 的用法。</p>
<pre class="brush: js">var animals = [
{ species: 'Lion', name: 'King' },
{ species: 'Whale', name: 'Fail' }
];
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
}).call(animals[i], i);
}
</pre>
<h3 id="使用_call_方法调用函数并且指定上下文的_this">使用 <code>call</code> 方法调用函数并且指定上下文的 '<code>this</code>'</h3>
<p>在下面的例子中,当调用 <code>greet</code> 方法的时候,该方法的<code>this</code>值会绑定到 <code>obj</code> 对象。</p>
<pre class="brush: js">function greet() {
var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
console.log(reply);
}
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
greet.call(obj); // cats typically sleep between 12 and 16 hours
</pre>
<h3 id="使用_call_方法调用函数并且不指定第一个参数(argument)">使用 <code><strong>call</strong></code> 方法调用函数并且不指定第一个参数(<code>argument</code>)</h3>
<p>在下面的例子中,我们调用了 <code>display</code> 方法,但并没有传递它的第一个参数。如果没有传递第一个参数,<code>this</code> 的值将会被绑定为全局对象。</p>
<pre class="brush: js">var sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // sData value is Wisen</pre>
<div class="note">
<p><strong>注意:</strong>在严格模式下,<code>this</code> 的值将会是 <code>undefined</code>。见下文。</p>
</div>
<pre class="brush: js">'use strict';
var sData = 'Wisen';
function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // Cannot read the property of 'sData' of undefined</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('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>初始定义。在 JavaScript 1.3 中实现。</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-15.3.4.4', 'Function.prototype.call')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-function.prototype.call', 'Function.prototype.call')}}</td>
<td>{{Spec2('ES6')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-function.prototype.call', 'Function.prototype.call')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p>{{Compat("javascript.builtins.Function.call")}}</p>
<h2 id="See_also" name="See_also">相关链接</h2>
<ul>
<li>{{jsxref("Function.prototype.bind()")}}</li>
<li>{{jsxref("Function.prototype.apply()")}}</li>
<li><a href="/zh-CN/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript">JavaScript 面向对象入门</a></li>
</ul>
|