diff options
Diffstat (limited to 'files/pt-pt/web/javascript/reference/functions')
4 files changed, 1455 insertions, 0 deletions
diff --git a/files/pt-pt/web/javascript/reference/functions/arguments/index.html b/files/pt-pt/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..c7ac84a4b9 --- /dev/null +++ b/files/pt-pt/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,228 @@ +--- +title: O objeto arguments +slug: Web/JavaScript/Reference/Funcoes/arguments +tags: + - Class + - Funções + - JavaScript + - Referencia + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +<p>{{JSSidebar("Functions")}}</p> + +<p><strong><code>arguments</code></strong> é um objeto semelhante a uma "<code>Matiz</code>" acessível dentro de <em>functions </em>que contém os valores dos argumentos passados para essa função.</p> + +<div class="blockIndicator note"> +<p><strong>Nota:</strong> If you're writing ES6 compatible code, then <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameters</a> should be preferred.</p> +</div> + +<div class="blockIndicator note"> +<p><strong>Nota:</strong> “Array-like” means that <code>arguments</code> has a <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments/length">length</a></code> property and properties indexed from zero, but it doesn't have {{JSxRef("Array")}}'s built-in methods like <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">forEach</a></code> and <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a></code>. See <a href="#Description">§Description</a> for details.</p> +</div> + +<div>{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}</div> + + + +<h2 id="Sintaxe">Sintaxe</h2> + +<pre class="syntaxbox">arguments</pre> + +<h2 id="Descrição">Descrição</h2> + +<p>The <code>arguments</code> object is a local variable available within all non-<a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow</a> functions. You can refer to a function's arguments inside that function by using its <code>arguments</code> object. It has entries for each argument the function was called with, with the first entry's index at 0.</p> + +<p>For example, if a function is passed 3 arguments, you can access them as follows:</p> + +<pre class="brush: js">arguments[0] // first argument +arguments[1] // second argument +arguments[2] // third argument +</pre> + +<p>Each argument can also be set or reassigned:</p> + +<pre class="brush: js">arguments[1] = 'new value'; +</pre> + +<p>The <code>arguments</code> object is not an {{JSxRef("Array")}}. It is similar, but does not have any <code>Array</code> properties except <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments/length">length</a></code>. For example, it does not have the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop">pop</a></code> method. However, it can be converted to a real <code>Array</code>:</p> + +<pre class="brush: js">var args = Array.prototype.slice.call(arguments); +// Using an array literal is shorter than above but allocates an empty array +var args = [].slice.call(arguments); +</pre> + +<p>As you can do with any Array-like object, you can use ES2015's {{JSxRef("Array.from()")}} method or <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread operator</a> to convert <code>arguments</code> to a real Array:</p> + +<pre>let args = Array.from(arguments); +// or +let args = [...arguments];</pre> + +<p>The <code>arguments</code> object is useful for functions called with more arguments than they are formally declared to accept. This technique is useful for functions that can be passed a variable number of arguments, such as <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min">Math.min()</a></code>. This example function accepts any number of string arguments and returns the longest one:</p> + +<pre class="brush: js">function longestString() { + var longest = ''; + for (var i=0; i < arguments.length; i++) { + if (arguments[i].length > longest.length) { + longest = arguments[i]; + } + } + return longest; +} +</pre> + +<p>You can use <code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code> to count how many arguments the function was called with. If you instead want to count how many parameters a function is declared to accept, inspect that function's <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function/length">length</a></code> property.</p> + +<h3 id="Utilizar_typeof_com_Arguments">Utilizar <code>typeof</code> com <em>Arguments</em></h3> + +<p>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a></code> operator returns <code>'object'</code> when used with <code>arguments</code></p> + +<pre class="brush: js">console.log(typeof arguments); // 'object' </pre> + +<p>The type of individual arguments can be determined by indexing <code>arguments</code>:</p> + +<pre>console.log(typeof arguments[0]); // returns the type of the first argument</pre> + +<h2 id="Propriedades">Propriedades</h2> + +<dl> + <dt></dt> + <dt>{{jsxref("Functions/arguments/callee", "arguments.callee")}}</dt> + <dd>Reference to the currently executing function that the arguments belong to.</dd> + <dt>{{jsxref("Functions/arguments/length", "arguments.length")}}</dt> + <dd>The number of arguments that were passed to the function.</dd> + <dt>{{jsxref("Functions/arguments/@@iterator", "arguments[@@iterator]")}}</dt> + <dd>Returns a new {{jsxref("Array/@@iterator", "Array iterator", "", 0)}} object that contains the values for each index in <code>arguments</code>.</dd> +</dl> + +<h2 id="Exemplos">Exemplos</h2> + +<h3 id="Definir_uma_function_que_concatena_várias_strings">Definir uma <em>function</em> que concatena várias <em>strings</em></h3> + +<p>This example defines a function that concatenates several strings. The function's only formal argument is a string containing the characters that separate the items to concatenate.</p> + +<pre class="brush:js">function myConcat(separator) { + var args = Array.prototype.slice.call(arguments, 1); + return args.join(separator); +}</pre> + +<p>You can pass as many arguments as you like to this function. It returns a string list using each argument in the list:</p> + +<pre class="brush:js">// returns "red, orange, blue" +myConcat(', ', 'red', 'orange', 'blue'); + +// returns "elephant; giraffe; lion; cheetah" +myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah'); + +// returns "sage. basil. oregano. pepper. parsley" +myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');</pre> + +<h3 id="Definir_uma_function_que_cria_listas_HTML">Definir uma <em>function</em> que cria listas HTML</h3> + +<p>This example defines a function that creates a string containing HTML for a list. The only formal argument for the function is a string that is "<code>u</code>" if the list is to be unordered (bulleted), or "<code>o</code>" if the list is to be ordered (numbered). The function is defined as follows:</p> + +<pre class="brush:js">function list(type) { + var html = '<' + type + 'l><li>'; + var args = Array.prototype.slice.call(arguments, 1); + html += args.join('</li><li>'); + html += '</li></' + type + 'l>'; // end list + + return html; +}</pre> + +<p>You can pass any number of arguments to this function, and it adds each argument as a list item to a list of the type indicated. For example:</p> + +<pre class="brush:js">var listHTML = list('u', 'One', 'Two', 'Three'); + +/* listHTML is: +"<ul><li>One</li><li>Two</li><li>Three</li></ul>" +*/</pre> + +<h3 id="Parâmetros_Rest_predefinição_e_desestruturados">Parâmetros Rest, predefinição, e desestruturados</h3> + +<p>The <code>arguments</code> object can be used in conjunction with <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest</a>, <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">default</a>, and <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructured</a> parameters.</p> + +<pre class="brush: js">function foo(...args) { + return args; +} +foo(1, 2, 3); // [1,2,3] +</pre> + +<p>While the presence of rest, default, or destructured parameters does not alter the <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode#Making_eval_and_arguments_simpler">behavior of the <code>arguments</code> object in strict mode code</a>, there is a subtle difference for non-strict code.</p> + +<p>In strict-mode code, the <code>arguments</code> object behaves the same whether or not a function is passed rest, default, or destructured parameters. That is, assigning new values to variables in the body of the function will not affect the <code>arguments</code> object. Nor will assigning new variables to the <code>arguments</code> object affect the value of variables.</p> + +<div class="blockIndicator note"> +<p><strong>Nota:</strong> You cannot write a <code>"use strict";</code> directive in the body of a function definition that accepts rest, default, or destructured parameters. Doing so will throw <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Strict_Non_Simple_Params">a syntax error</a>.</p> +</div> + +<p>Non-strict functions that are passed only simple parameters (that is, not rest, default, or restructured parameters) will sync the value of variables new values in the body of the function with the <code>arguments</code> object, and vice versa:</p> + +<pre class="brush: js">function func(a) { + arguments[0] = 99; // updating arguments[0] also updates a + console.log(a); +} +func(10); // 99 +</pre> + +<p>And also:</p> + +<pre class="brush: js">function func(a) { + a = 99; // updating a also updates arguments[0] + console.log(arguments[0]); +} +func(10); // 99 +</pre> + +<p>Conversely, non-strict functions that <strong>are</strong> passed rest, default, or destructured parameters <strong>will not</strong> sync new values assigned to argument variables in the function body with the <code>arguments</code> object. Instead, the <code>arguments</code> object in non-strict functions with complex parameters <strong>will always</strong> reflect the values passed to the function when the function was called (this is the same behavior as exhibited by all strict-mode functions, regardless of the type of variables they are passed):</p> + +<pre class="brush: js">function func(a = 55) { + arguments[0] = 99; // updating arguments[0] does not also update a + console.log(a); +} +func(10); // 10</pre> + +<p>E também:</p> + +<pre class="brush: js">function func(a = 55) { + a = 99; // updating a does not also update arguments[0] + console.log(arguments[0]); +} +func(10); // 10 +</pre> + +<p>E também:</p> + +<pre class="brush: js">// An untracked default parameter +function func(a = 55) { + console.log(arguments[0]); +} +func(); // undefined</pre> + +<h2 id="Especificações">Especificações</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Especificação</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibildiade_de_navegador">Compatibildiade de navegador</h2> + + + +<p>{{Compat("javascript.functions.arguments")}}</p> + +<h2 id="Consulte_também">Consulte também</h2> + +<ul> + <li>{{JSxRef("Function")}}</li> + <li><a href="/pt-PT/docs/Web/JavaScript/Reference/Funcoes/parametros_rest">Parâmetros Rest</a></li> +</ul> diff --git a/files/pt-pt/web/javascript/reference/functions/arrow_functions/index.html b/files/pt-pt/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..aa7b7b3121 --- /dev/null +++ b/files/pt-pt/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,399 @@ +--- +title: Expressões da função "Seta" +slug: Web/JavaScript/Reference/Funcoes/Funcoes_seta +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Uma <strong>expressão da função seta</strong> é uma alternativa sintaticamente compacta a uma expressão de <a href="/pt-PT/docs/Web/JavaScript/Reference/Operadores/função">expressão de função</a> regular, embora sem as suas próprias associações às palavras-chave <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/super">super</a></code>, ou <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a></code>. As expressões de função (<em>function</em>) de seta são inadequadas como métodos, e não podem ser utilziadas como construtores.</p> + +<div>{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}</div> + +<h2 id="Sintaxe">Sintaxe</h2> + +<h3 id="Basic_syntax">Basic syntax</h3> + +<pre class="syntaxbox">(param1, param2, …, paramN) => { statements } +(param1, param2, …, paramN) => expression +// equivalent to: => { return expression; } + +// Parentheses are optional when there's only one parameter name: +(singleParam) => { statements } +singleParam => { statements } + +// The parameter list for a function with no parameters should be written with a pair of parentheses. +() => { statements } +</pre> + +<h3 id="Advanced_syntax">Advanced syntax</h3> + +<pre class="syntaxbox">// Parenthesize the body of a function to return an object literal expression: +params => ({foo: bar}) + +// <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Rest_parameters">Rest parameters</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">default parameters</a> are supported +(param1, param2, ...rest) => { statements } +(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { +statements } + +// <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destructuring</a> within the parameter list is also supported +var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; +f(); // 6 +</pre> + +<h2 id="Descrição">Descrição</h2> + +<p>See also <a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a>.</p> + +<p>Two factors influenced the introduction of arrow functions: the need for shorter functions and the behavior of the <code>this</code> keyword.</p> + +<h3 id="Funções_curtas">Funções curtas</h3> + +<pre class="brush: js">var elements = [ + 'Hydrogen', + 'Helium', + 'Lithium', + 'Beryllium' +]; + +// This statement returns the array: [8, 6, 7, 9] +elements.<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a>(function(element) { + return element.length; +}); + +// The regular function above can be written as the arrow function below +elements.map((element) => { + return element.length; +}); // [8, 6, 7, 9] + +// When there is only one parameter, we can remove the surrounding parentheses +elements.<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a>(element => { + return element.length; +}); // [8, 6, 7, 9] + +// When the only statement in an arrow function is `return`, we can remove `return` and remove +// the surrounding curly brackets +elements.map(element => element.length); // [8, 6, 7, 9] + +// In this case, because we only need the length property, we can use destructuring parameter: +// Notice that the `length` corresponds to the property we want to get whereas the +// obviously non-special `lengthFooBArX` is just the name of a variable which can be changed +// to any valid variable name you want +elements.<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a>(({ length: lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9] + +// This destructuring parameter assignment can also be written as seen below. However, note that in +// this example we are not assigning `length` value to the made up property. Instead, the literal name +// itself of the variable `length` is used as the property we want to retrieve from the object. +elements.<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a>(({ length }) => length); // [8, 6, 7, 9] +</pre> + +<h3 id="No_separate_this">No separate <code>this</code></h3> + +<p>Before arrow functions, every new function defined its own <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a></code> value based on how the function was called:</p> + +<ul> + <li>A new object in the case of a constructor.</li> + <li><code>undefined</code> in <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a> function calls.</li> + <li>The base object if the function was called as an "object method".</li> + <li>etc.</li> +</ul> + +<p>This proved to be less than ideal with an object-oriented style of programming.</p> + +<pre class="brush: js">function Person() { + // The Person() constructor defines `this` as an instance of itself. + this.age = 0; + + setInterval(function growUp() { + // In non-strict mode, the growUp() function defines `this` + // as the global object (because it's where growUp() is executed.), + // which is different from the `this` + // defined by the Person() constructor. + this.age++; + }, 1000); +} + +var p = new Person();</pre> + +<p>In ECMAScript 3/5, the <code>this</code> issue was fixable by assigning the value in <code>this</code> to a variable that could be closed over.</p> + +<pre class="brush: js">function Person() { + var that = this; + that.age = 0; + + setInterval(function growUp() { + // The callback refers to the `that` variable of which + // the value is the expected object. + that.age++; + }, 1000); +}</pre> + +<p>Alternatively, a <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bound function</a> could be created so that a preassigned <code>this</code> value would be passed to the bound target function (the <code>growUp()</code> function in the example above).</p> + +<p>An arrow function does not have its own <code>this</code>. The <code>this</code> value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for <code>this</code> which is not present in current scope, an arrow function ends up finding the <code>this</code> from its enclosing scope.</p> + +<p>Thus, in the following code, the <code>this</code> within the function that is passed to <code>setInterval</code> has the same value as the <code>this</code> in the lexically enclosing function:</p> + +<pre class="brush: js">function Person(){ + this.age = 0; + + setInterval(() => { + this.age++; // |this| properly refers to the Person object + }, 1000); +} + +var p = new Person();</pre> + +<h4 id="Relation_with_strict_mode">Relation with strict mode</h4> + +<p>Given that <code>this</code> comes from the surrounding lexical context, <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a> rules with regard to <code>this</code> are ignored.</p> + +<pre class="brush: js">var f = () => { 'use strict'; return this; }; +f() === window; // or the global object</pre> + +<p>All other strict mode rules apply normally.</p> + +<h4 id="Invoked_through_call_or_apply">Invoked through call or apply</h4> + +<p>Since arrow functions do not have their own <code>this</code>, the methods <code>call()</code> and <code>apply()</code> can only pass in parameters. Any <code>this</code> argument is ignored.</p> + +<pre class="brush: js">var adder = { + base: 1, + + add: function(a) { + var f = v => v + this.base; + return f(a); + }, + + addThruCall: function(a) { + var f = v => v + this.base; + var b = { + base: 2 + }; + + return f.call(b, a); + } +}; + +console.log(adder.add(1)); // This would log 2 +console.log(adder.addThruCall(1)); // This would log 2 still</pre> + +<h3 id="No_binding_of_arguments">No binding of <code>arguments</code></h3> + +<p>Arrow functions do not have their own <a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments"><code>arguments</code> object</a>. Thus, in this example, <code>arguments</code> is simply a reference to the arguments of the enclosing scope:</p> + +<pre class="brush: js">var arguments = [1, 2, 3]; +var arr = () => arguments[0]; + +arr(); // 1 + +function foo(n) { + var f = () => arguments[0] + n; // <em>foo</em>'s implicit arguments binding. arguments[0] is n + return f(); +} + +foo(3); // 6</pre> + +<p>In most cases, using <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameters</a> is a good alternative to using an <code>arguments</code> object.</p> + +<pre class="brush: js">function foo(n) { + var f = (...args) => args[0] + n; + return f(10); +} + +foo(1); // 11</pre> + +<h3 id="Arrow_functions_used_as_methods">Arrow functions used as methods</h3> + +<p>As stated previously, arrow function expressions are best suited for non-method functions. Let's see what happens when we try to use them as methods:</p> + +<pre class="brush: js">'use strict'; + +var obj = { // does not create a new scope + i: 10, + b: () => console.log(this.i, this), + c: function() { + console.log(this.i, this); + } +} + +obj.b(); // prints undefined, Window {...} (or the global object) +obj.c(); // prints 10, Object {...}</pre> + +<p>Arrow functions do not have their own <code>this</code>. Another example involving {{jsxref("Object.defineProperty()")}}:</p> + +<pre class="brush: js">'use strict'; + +var obj = { + a: 10 +}; + +Object.defineProperty(obj, 'b', { + get: () => { + console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object) + return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined' + } +}); +</pre> + +<h3 id="Use_of_the_new_operator">Use of the <code>new</code> operator</h3> + +<p>Arrow functions cannot be used as constructors and will throw an error when used with <code>new</code>.</p> + +<pre class="brush: js">var Foo = () => {}; +var foo = new Foo(); // TypeError: Foo is not a constructor</pre> + +<h3 id="Use_of_prototype_property">Use of <code>prototype</code> property</h3> + +<p>Arrow functions do not have a <code>prototype</code> property.</p> + +<pre class="brush: js">var Foo = () => {}; +console.log(Foo.prototype); // undefined +</pre> + +<h3 id="Use_of_the_yield_keyword">Use of the <code>yield</code> keyword</h3> + +<p>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/yield">yield</a></code> keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.</p> + +<h2 id="Function_body">Function body</h2> + +<p>Arrow functions can have either a "concise body" or the usual "block body".</p> + +<p>In a concise body, only an expression is specified, which becomes the implicit return value. In a block body, you must use an explicit <code>return</code> statement.</p> + +<pre class="brush: js">var func = x => x * x; +// concise body syntax, implied "return" + +var func = (x, y) => { return x + y; }; +// with block body, explicit "return" needed +</pre> + +<h2 id="Returning_object_literals">Returning object literals</h2> + +<p>Keep in mind that returning object literals using the concise body syntax <code>params => {object:literal}</code> will not work as expected.</p> + +<pre class="brush: js">var func = () => { foo: 1 }; +// Calling func() returns undefined! + +var func = () => { foo: function() {} }; +// SyntaxError: function statement requires a name</pre> + +<p>This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. <code>foo</code> is treated like a label, not a key in an object literal).</p> + +<p>You must wrap the object literal in parentheses:</p> + +<pre class="brush: js">var func = () => ({ foo: 1 });</pre> + +<h2 id="Line_breaks">Line breaks</h2> + +<p>An arrow function cannot contain a line break between its parameters and its arrow.</p> + +<pre class="brush: js">var func = (a, b, c) + => 1; +// SyntaxError: expected expression, got '=>'</pre> + +<p>However, this can be amended by putting the line break after the arrow or using parentheses/braces as seen below to ensure that the code stays pretty and fluffy. You can also put line breaks between arguments.</p> + +<pre class="brush: js">var func = (a, b, c) => + 1; + +var func = (a, b, c) => ( + 1 +); + +var func = (a, b, c) => { + return 1 +}; + +var func = ( + a, + b, + c +) => 1; + +// no SyntaxError thrown</pre> + +<h2 id="Parsing_order">Parsing order</h2> + +<p>Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">operator precedence</a> compared to regular functions.</p> + +<pre class="brush: js">let callback; + +callback = callback || function() {}; // ok + +callback = callback || () => {}; +// SyntaxError: invalid arrow-function arguments + +callback = callback || (() => {}); // ok +</pre> + +<h2 id="More_examples">More examples</h2> + +<pre class="brush: js">// An empty arrow function returns undefined +let empty = () => {}; + +(() => 'foobar')(); +// Returns "foobar" +// (this is an <a href="/en-US/docs/Glossary/IIFE">Immediately Invoked Function Expression</a>) + +var simple = a => a > 15 ? 15 : a; +simple(16); // 15 +simple(10); // 10 + +let max = (a, b) => a > b ? a : b; + +// Easy array filtering, mapping, ... + +var arr = [5, 6, 13, 0, 1, 18, 23]; + +var sum = arr.reduce((a, b) => a + b); +// 66 + +var even = arr.filter(v => v % 2 == 0); +// [6, 0, 18] + +var double = arr.map(v => v * 2); +// [10, 12, 26, 0, 2, 36, 46] + +// More concise promise chains +promise.then(a => { + // ... +}).then(b => { + // ... +}); + +// Parameterless arrow functions that are visually easier to parse +setTimeout( () => { + console.log('I happen sooner'); + setTimeout( () => { + // deeper code + console.log('I happen later'); + }, 1); +}, 1); +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<div> + + +<p>{{Compat("javascript.functions.arrow_functions")}}</p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a></li> +</ul> diff --git a/files/pt-pt/web/javascript/reference/functions/index.html b/files/pt-pt/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..02b35fc7bd --- /dev/null +++ b/files/pt-pt/web/javascript/reference/functions/index.html @@ -0,0 +1,594 @@ +--- +title: Funções +slug: Web/JavaScript/Reference/Funcoes +tags: + - Constructor + - Função + - Funções + - JavaScript + - Parâmetro + - parâmetros +translation_of: Web/JavaScript/Reference/Functions +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Generally speaking, a function is a "subprogram" that can be <em>called</em> by code external (or internal in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the <em>function body</em>. Values can be <em>passed</em> to a function, and the function will <em>return</em> a value.</p> + +<p>In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function">Function</a></code> objects.</p> + +<p>For more examples and explanations, see also the <a href="/en-US/docs/Web/JavaScript/Guide/Functions">JavaScript guide about functions</a>.</p> + +<h2 id="Descrição">Descrição</h2> + +<p>Every function in JavaScript is a <code>Function</code> object. See {{jsxref("Function")}} for information on properties and methods of <code>Function</code> objects.</p> + +<p>To return a value other than the default, a function must have a <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/return">return</a></code> statement that specifies the value to return. A function without a return statement will return a default value. In the case of a <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a> called with the <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/new">new</a></code> keyword, the default value is the value of its <code>this</code> parameter. For all other functions, the default return value is {{jsxref("undefined")}}.</p> + +<p>The parameters of a function call are the function's <em>arguments</em>. Arguments are passed to functions <em>by value</em>. If the function changes the value of an argument, this change is not reflected globally or in the calling function. However, object references are values, too, and they are special: if the function changes the referred object's properties, that change is visible outside the function, as shown in the following example:</p> + +<pre class="brush: js">/* Declare the function 'myFunc' */ +function myFunc(theObject) { + theObject.brand = "Toyota"; +} + +/* + * Declare variable 'mycar'; + * create and initialize a new Object; + * assign reference to it to 'mycar' + */ +var mycar = { + brand: "Honda", + model: "Accord", + year: 1998 +}; + +/* Logs 'Honda' */ +console.log(mycar.brand); + +/* Pass object reference to the function */ +myFunc(mycar); + +/* + * Logs 'Toyota' as the value of the 'brand' property + * of the object, as changed to by the function. + */ +console.log(mycar.brand); +</pre> + +<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Operators/this"><code>this</code> keyword</a> does not refer to the currently executing function, so you must refer to <code>Function</code> objects by name, even within the function body.</p> + +<h2 id="Definindo_funções">Definindo funções</h2> + +<p>There are several ways to define functions:</p> + +<h3 id="The_function_declaration_(function_statement)">The function declaration (<code>function</code> statement)</h3> + +<p>There is a special syntax for declaring functions (see <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function">function statement</a> for details):</p> + +<pre class="syntaxbox">function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>The function name.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>The name of an argument to be passed to the function. A function can have up to 255 arguments.</dd> +</dl> + +<dl> + <dt><code>statements</code></dt> + <dd>The statements comprising the body of the function.</dd> +</dl> + +<h3 id="The_function_expression_(function_expression)">The function expression (<code>function</code> expression)</h3> + +<p>A function expression is similar to and has the same syntax as a function declaration (see <a href="/en-US/docs/Web/JavaScript/Reference/Operators/function">function expression</a> for details). A function expression may be a part of a larger expression. One can define "named" function expressions (where the name of the expression might be used in the call stack for example) or "anonymous" function expressions. Function expressions are not <em>hoisted</em> onto the beginning of the scope, therefore they cannot be used before they appear in the code.</p> + +<pre class="syntaxbox">function [<em>name</em>]([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>The function name. Can be omitted, in which case the function becomes known as an anonymous function.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>The name of an argument to be passed to the function. A function can have up to 255 arguments.</dd> + <dt><code>statements</code></dt> + <dd>The statements comprising the body of the function.</dd> +</dl> + +<p>Here is an example of an <strong>anonymous</strong> function expression (the <code>name</code> is not used):</p> + +<pre class="brush: js">var myFunction = function() { + statements +}</pre> + +<p>It is also possible to provide a name inside the definition in order to create a <strong>named</strong> function expression:</p> + +<pre class="brush: js">var myFunction = function namedFunction(){ + statements +} +</pre> + +<p>One of the benefit of creating a named function expression is that in case we encounted an error, the stack trace will contain the name of the function, making it easier to find the origin of the error.</p> + +<p>As we can see, both examples do not start with the <code>function</code> keyword. Statements involving functions which do not start with <code>function</code> are function expressions.</p> + +<p>When functions are used only once, a common pattern is an <strong>IIFE (<em>Immediately Invokable Function Expression</em>)</strong>.</p> + +<pre class="brush: js">(function() { + statements +})();</pre> + +<p>IIFE are function expressions that are invoked as soon as the function is declared.</p> + +<h3 id="The_generator_function_declaration_(function*_statement)">The generator function declaration (<code>function*</code> statement)</h3> + +<p>There is a special syntax for generator function declarations (see {{jsxref('Statements/function*', 'function* statement')}} for details):</p> + +<pre class="syntaxbox">function* <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>The function name.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>The name of an argument to be passed to the function. A function can have up to 255 arguments.</dd> +</dl> + +<dl> + <dt><code>statements</code></dt> + <dd>The statements comprising the body of the function.</dd> +</dl> + +<h3 id="The_generator_function_expression_(function*_expression)">The generator function expression (<code>function*</code> expression)</h3> + +<p>A generator function expression is similar to and has the same syntax as a generator function declaration (see {{jsxref('Operators/function*', 'function* expression')}} for details):</p> + +<pre class="syntaxbox">function* [<em>name</em>]([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>The function name. Can be omitted, in which case the function becomes known as an anonymous function.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>The name of an argument to be passed to the function. A function can have up to 255 arguments.</dd> + <dt><code>statements</code></dt> + <dd>The statements comprising the body of the function.</dd> +</dl> + +<h3 id="The_arrow_function_expression_(>)">The arrow function expression (=>)</h3> + +<p>An arrow function expression has a shorter syntax and lexically binds its <code>this</code> value (see <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a> for details):</p> + +<pre class="syntaxbox">([param[, param]]) => { + statements +} + +param => expression +</pre> + +<dl> + <dt><code>param</code></dt> + <dd>The name of an argument. Zero arguments need to be indicated with <code>()</code>. For only one argument, the parentheses are not required. (like <code>foo => 1</code>)</dd> + <dt><code>statements or expression</code></dt> + <dd>Multiple statements need to be enclosed in brackets. A single expression requires no brackets. The expression is also the implicit return value of the function.</dd> +</dl> + +<h3 id="The_Function_constructor">The <code>Function</code> constructor</h3> + +<div class="note"> +<p><strong>Note:</strong> Using the <code>Function</code> constructor to create functions is not recommended since it needs the function body as a string which may prevent some JS engine optimizations and can also cause other problems.</p> +</div> + +<p>As all other objects, {{jsxref("Function")}} objects can be created using the <code>new</code> operator:</p> + +<pre class="syntaxbox">new Function (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>) +</pre> + +<dl> + <dt><code>arg1, arg2, ... arg<em>N</em></code></dt> + <dd>Zero or more names to be used by the function as formal parameters. Each must be a proper JavaScript identifier.</dd> +</dl> + +<dl> + <dt><code>functionBody</code></dt> + <dd>A string containing the JavaScript statements comprising the function body.</dd> +</dl> + +<p>Invoking the <code>Function</code> constructor as a function (without using the <code>new</code> operator) has the same effect as invoking it as a constructor.</p> + +<h3 id="The_GeneratorFunction_constructor">The <code>GeneratorFunction</code> constructor</h3> + +<div class="note"> +<p><strong>Note:</strong> <code>GeneratorFunction</code> is not a global object, but could be obtained from generator function instance (see {{jsxref("GeneratorFunction")}} for more detail).</p> +</div> + +<div class="note"> +<p><strong>Note:</strong> Using the <code>GeneratorFunction</code> constructor to create functions is not recommended since it needs the function body as a string which may prevent some JS engine optimizations and can also cause other problems.</p> +</div> + +<p>As all other objects, {{jsxref("GeneratorFunction")}} objects can be created using the <code>new</code> operator:</p> + +<pre class="syntaxbox">new GeneratorFunction (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>) +</pre> + +<dl> + <dt><code>arg1, arg2, ... arg<em>N</em></code></dt> + <dd>Zero or more names to be used by the function as formal argument names. Each must be a string that conforms to the rules for a valid JavaScript identifier or a list of such strings separated with a comma; for example "<code>x</code>", "<code>theValue</code>", or "<code>a,b</code>".</dd> +</dl> + +<dl> + <dt><code>functionBody</code></dt> + <dd>A string containing the JavaScript statements comprising the function definition.</dd> +</dl> + +<p>Invoking the <code>Function</code> constructor as a function (without using the <code>new</code> operator) has the same effect as invoking it as a constructor.</p> + +<h2 id="Parâmetros_de_função">Parâmetros de função</h2> + +<h3 id="Parâmetros_predefinidos">Parâmetros predefinidos</h3> + +<p>Default function parameters allow formal parameters to be initialized with default values if no value or <code>undefined</code> is passed. For more details, see<a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters"> default parameters</a>.</p> + +<h3 id="Parâmetros_Rest">Parâmetros <em>Rest</em></h3> + +<p>The rest parameter syntax allows to represent an indefinite number of arguments as an array. For more details, see <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameters</a>.</p> + +<h2 id="O_objeto_arguments">O objeto <em><code>arguments</code></em></h2> + +<p>You can refer to a function's arguments within the function by using the <code>arguments</code> object. See <a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>.</p> + +<ul> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a></code>: An array-like object containing the arguments passed to the currently executing function.</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code> {{Deprecated_inline}}: The currently executing function.</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/caller">arguments.caller</a></code> {{Obsolete_inline}} : The function that invoked the currently executing function.</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code>: The number of arguments passed to the function.</li> +</ul> + +<h2 id="Definindo_funções_de_método">Definindo funções de método</h2> + +<h3 id="Getter_and_setter_functions">Getter and setter functions</h3> + +<p>You can define getters (accessor methods) and setters (mutator methods) on any standard built-in object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.</p> + +<dl> + <dt><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></dt> + <dd> + <p>Binds an object property to a function that will be called when that property is looked up.</p> + </dd> + <dt><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></dt> + <dd>Binds an object property to a function to be called when there is an attempt to set that property.</dd> +</dl> + +<h3 id="Method_definition_syntax">Method definition syntax</h3> + +<p>Starting with ECMAScript 2015, you are able to define own methods in a shorter syntax, similar to the getters and setters. See <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method definitions</a> for more information.</p> + +<pre class="brush: js">var obj = { + foo() {}, + bar() {} +};</pre> + +<h2 id="Constructor_vs._declaration_vs._expression">Constructor vs. declaration vs. expression</h2> + +<p>Compare the following:</p> + +<p>A function defined with the <code>Function</code> <em>constructor</em> assigned to the variable <code>multiply:</code></p> + +<pre class="brush: js">var multiply = new Function('x', 'y', 'return x * y');</pre> + +<p>A <em>function declaration</em> of a function named <code>multiply</code>:</p> + +<pre class="brush: js">function multiply(x, y) { + return x * y; +} // there is no semicolon here +</pre> + +<p>A <em>function expression</em> of an anonymous function assigned to the variable <code>multiply:</code></p> + +<pre class="brush: js">var multiply = function(x, y) { + return x * y; +}; +</pre> + +<p>A <em>function expression</em> of a function named <code>func_name</code> assigned to the variable <code>multiply:</code></p> + +<pre class="brush: js">var multiply = function func_name(x, y) { + return x * y; +}; +</pre> + +<h3 id="Differences">Differences</h3> + +<p>All do approximately the same thing, with a few subtle differences:</p> + +<p>There is a distinction between the function name and the variable the function is assigned to. The function name cannot be changed, while the variable the function is assigned to can be reassigned. The function name can be used only within the function's body. Attempting to use it outside the function's body results in an error (or <code>undefined</code> if the function name was previously declared via a <code>var</code> statement). For example:</p> + +<pre class="brush: js">var y = function x() {}; +alert(x); // throws an error +</pre> + +<p>The function name also appears when the function is serialized via <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString"><code>Function</code>'s toString method</a>.</p> + +<p>On the other hand, the variable the function is assigned to is limited only by its scope, which is guaranteed to include the scope in which the function is declared.</p> + +<p>As the 4th example shows, the function name can be different from the variable the function is assigned to. They have no relation to each other. A function declaration also creates a variable with the same name as the function name. Thus, unlike those defined by function expressions, functions defined by function declarations can be accessed by their name in the scope they were defined in:</p> + +<p>A function defined by '<code>new Function'</code> does not have a function name. However, in the <a href="/en-US/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> JavaScript engine, the serialized form of the function shows as if it has the name "anonymous". For example, <code>alert(new Function())</code> outputs:</p> + +<pre class="brush: js">function anonymous() { +} +</pre> + +<p>Since the function actually does not have a name, <code>anonymous</code> is not a variable that can be accessed within the function. For example, the following would result in an error:</p> + +<pre class="brush: js">var foo = new Function("alert(anonymous);"); +foo(); +</pre> + +<p>Unlike functions defined by function expressions or by the <code>Function</code> constructor, a function defined by a function declaration can be used before the function declaration itself. For example:</p> + +<pre class="brush: js">foo(); // alerts FOO! +function foo() { + alert('FOO!'); +} +</pre> + +<p>A function defined by a function expression or by a function declaration inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a <code>Function</code> constructor does not inherit any scope other than the global scope (which all functions inherit).</p> + +<pre class="brush: js">/* + * Declare and initialize a variable 'p' (global) + * and a function 'myFunc' (to change the scope) inside which + * declare a varible with same name 'p' (current) and + * define three functions using three different ways:- + * 1. function declaration + * 2. function expression + * 3. function constructor + * each of which will log 'p' + */ +var p = 5; +function myFunc() { + var p = 9; + + function decl() { + console.log(p); + } + var expr = function() { + console.log(p); + }; + var cons = new Function('\tconsole.log(p);'); + + decl(); + expr(); + cons(); +} +myFunc(); + +/* + * Logs:- + * 9 - for 'decl' by function declaration (current scope) + * 9 - for 'expr' by function expression (current scope) + * 5 - for 'cons' by Function constructor (global scope) + */ +</pre> + +<p>Functions defined by function expressions and function declarations are parsed only once, while those defined by the <code>Function</code> constructor are not. That is, the function body string passed to the <code>Function</code> constructor must be parsed each and every time the constructor is called. Although a function expression creates a closure every time, the function body is not reparsed, so function expressions are still faster than "<code>new Function(...)</code>". Therefore the <code>Function</code> constructor should generally be avoided whenever possible.</p> + +<p>It should be noted, however, that function expressions and function declarations nested within the function generated by parsing a <code>Function constructor</code> 's string aren't parsed repeatedly. For example:</p> + +<pre class="brush: js">var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))(); +foo(); // The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.</pre> + +<p>A function declaration is very easily (and often unintentionally) turned into a function expression. A function declaration ceases to be one when it either:</p> + +<ul> + <li>becomes part of an expression</li> + <li>is no longer a "source element" of a function or the script itself. A "source element" is a non-nested statement in the script or a function body:</li> +</ul> + +<pre class="brush: js">var x = 0; // source element +if (x === 0) { // source element + x = 10; // not a source element + function boo() {} // not a source element +} +function foo() { // source element + var y = 20; // source element + function bar() {} // source element + while (y === 10) { // source element + function blah() {} // not a source element + y++; // not a source element + } +} +</pre> + +<h3 id="Examples">Examples</h3> + +<pre class="brush: js">// function declaration +function foo() {} + +// function expression +(function bar() {}) + +// function expression +x = function hello() {} + + +if (x) { + // function expression + function world() {} +} + + +// function declaration +function a() { + // function declaration + function b() {} + if (0) { + // function expression + function c() {} + } +} +</pre> + +<h2 id="Block-level_functions">Block-level functions</h2> + +<p>In <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>, starting with ES2015, functions inside blocks are now scoped to that block. Prior to ES2015, block-level functions were forbidden in strict mode.</p> + +<pre class="brush: js">'use strict'; + +function f() { + return 1; +} + +{ + function f() { + return 2; + } +} + +f() === 1; // true + +// f() === 2 in non-strict mode +</pre> + +<h3 id="Block-level_functions_in_non-strict_code">Block-level functions in non-strict code</h3> + +<p>In a word: Don't.</p> + +<p>In non-strict code, function declarations inside blocks behave strangely. For example:</p> + +<pre class="brush: js">if (shouldDefineZero) { + function zero() { // DANGER: compatibility risk + console.log("This is zero."); + } +} +</pre> + +<p>ES2015 says that if <code>shouldDefineZero</code> is false, then <code>zero</code> should never be defined, since the block never executes. However, it's a new part of the standard. Historically, this was left unspecified, and some browsers would define <code>zero</code> whether the block executed or not.</p> + +<p>In <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>, all browsers that support ES2015 handle this the same way: <code>zero</code> is defined only if <code>shouldDefineZero</code> is true, and only in the scope of the <code>if</code>-block.</p> + +<p>A safer way to define functions conditionally is to assign a function expression to a variable:</p> + +<pre class="brush: js">var zero; +if (shouldDefineZero) { + zero = function() { + console.log("This is zero."); + }; +} +</pre> + +<h2 id="Exemplos">Exemplos</h2> + +<h3 id="Returning_a_formatted_number">Returning a formatted number</h3> + +<p>The following function returns a string containing the formatted representation of a number padded with leading zeros.</p> + +<pre class="brush: js">// This function returns a string padded with leading zeros +function padZeros(num, totalLen) { + var numStr = num.toString(); // Initialize return value as string + var numZeros = totalLen - numStr.length; // Calculate no. of zeros + for (var i = 1; i <= numZeros; i++) { + numStr = "0" + numStr; + } + return numStr; +} +</pre> + +<p>The following statements call the padZeros function.</p> + +<pre class="brush: js">var result; +result = padZeros(42,4); // returns "0042" +result = padZeros(42,2); // returns "42" +result = padZeros(5,4); // returns "0005" +</pre> + +<h3 id="Determining_whether_a_function_exists">Determining whether a function exists</h3> + +<p>You can determine whether a function exists by using the <code>typeof</code> operator. In the following example, a test is performed to determine if the <code>window</code> object has a property called <code>noFunc</code> that is a function. If so, it is used; otherwise some other action is taken.</p> + +<pre class="brush: js"> if ('function' === typeof window.noFunc) { + // use noFunc() + } else { + // do something else + } +</pre> + +<p>Note that in the <code>if</code> test, a reference to <code>noFunc</code> is used—there are no brackets "()" after the function name so the actual function is not called.</p> + +<h2 id="Especificações">Especificações</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('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.0</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>New: Arrow functions, Generator functions, default parameters, rest parameters.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilidade_de_navegador">Compatibilidade de navegador</h2> + + + +<p>{{Compat("javascript.functions")}}</p> + +<h2 id="Consulte_também">Consulte também</h2> + +<ul> + <li>{{jsxref("Statements/function", "function statement")}}</li> + <li>{{jsxref("Operators/function", "function expression")}}</li> + <li>{{jsxref("Statements/function*", "function* statement")}}</li> + <li>{{jsxref("Operators/function*", "function* expression")}}</li> + <li>{{jsxref("Function")}}</li> + <li>{{jsxref("GeneratorFunction")}}</li> + <li>{{jsxref("Functions/Arrow_functions", "Arrow functions")}}</li> + <li>{{jsxref("Functions/Default_parameters", "Default parameters")}}</li> + <li>{{jsxref("Functions/rest_parameters", "Rest parameters")}}</li> + <li>{{jsxref("Functions/arguments", "Arguments object")}}</li> + <li>{{jsxref("Functions/get", "getter")}}</li> + <li>{{jsxref("Functions/set", "setter")}}</li> + <li>{{jsxref("Functions/Method_definitions", "Method definitions")}}</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope">Functions and function scope</a></li> +</ul> diff --git a/files/pt-pt/web/javascript/reference/functions/rest_parameters/index.html b/files/pt-pt/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..a21cb25ed6 --- /dev/null +++ b/files/pt-pt/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,234 @@ +--- +title: Parâmetros Rest +slug: Web/JavaScript/Reference/Funcoes/parametros_rest +tags: + - Funcionalidade Linguagem + - Funções + - JavaScript + - Parametros Rest + - Rest +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +<div>Parâmetrois {{jsSidebar("Functions")}}</div> + +<p><span class="seoSummary">A sintaxe do <strong>parâmetro "rest"</strong> permite-nos representar um número indefinido de argumentos</span><span class="seoSummary">como um <em>array</em>.</span></p> + +<div>{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}</div> + + + +<h2 id="Sintaxe">Sintaxe</h2> + +<pre class="syntaxbox">function f(<var>a</var>, <var>b</var>, ...<var>theArgs</var>) { + // ... +}</pre> + +<h2 id="Descrição">Descrição</h2> + +<p>A function's last parameter can be prefixed with <code>...</code> which will cause all remaining (user supplied) arguments to be placed within a "standard" Javascript array.</p> + +<p>Only the last parameter can be a "rest parameter".</p> + +<pre class="brush: js">function myFun(<var>a</var>, <var>b</var>, ...<var>manyMoreArgs</var>) { + console.log("a", a) + console.log("b", b) + console.log("manyMoreArgs", manyMoreArgs) +} + +myFun("one", "two", "three", "four", "five", "six") + +// Console Output: +// a, one +// b, two +// manyMoreArgs, [three, four, five, six] +</pre> + +<h3 id="Difference_between_rest_parameters_and_the_arguments_object">Difference between rest parameters and the <code>arguments</code> object</h3> + +<p>There are three main differences between rest parameters and the {{jsxref("Functions/arguments", "arguments")}} object:</p> + +<ul> + <li>rest parameters are only the ones that haven't been given a separate name (i.e. formally defined in function expression), while the <code>arguments</code> object contains <em>all</em> arguments passed to the function;</li> + <li>the <code>arguments</code> object is not a real array, while rest parameters are {{jsxref("Global_Objects/Array", "Array")}} instances, meaning methods like {{jsxref("Array.sort", "sort")}}, {{jsxref("Array.map", "map")}}, {{jsxref("Array.forEach", "forEach")}} or {{jsxref("Array/pop", "pop")}} can be applied on it directly;</li> + <li>the <code>arguments</code> object has additional functionality specific to itself (like the <code>callee</code> property).</li> +</ul> + +<h3 id="From_arguments_to_an_array">From arguments to an array</h3> + +<p>Rest parameters have been introduced to reduce the boilerplate code that was induced by the arguments</p> + +<pre class="brush: js">// Before rest parameters, "arguments" could be converted to a normal array using: + +function f(a, b) { + + let normalArray = Array.prototype.slice.call(arguments) + // -- or -- + let normalArray = [].slice.call(arguments) + // -- or -- + let normalArray = Array.from(arguments) + + let first = normalArray.shift() // OK, gives the first argument + let first = arguments.shift() // ERROR (arguments is not a normal array) +} + +// Now, you can easily gain access to a normal array using a rest parameter + +function f(...args) { + let normalArray = args + let first = normalArray.shift() // OK, gives the first argument +} +</pre> + +<h3 id="Destructuring_rest_parameters">Destructuring rest parameters</h3> + +<p>Rest parameters can be destructured Arrays only (though objects will soon be supported). That means that their data can be unpacked into distinct variables. (See <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destructuring assignment</a>.)</p> + +<pre class="brush: js">function f(...[a, b, c]) { + return a + b + c; +} + +f(1) // NaN (b and c are undefined) +f(1, 2, 3) // 6 +f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured) +</pre> + +<div class="blockIndicator note"> +<h4 id="Fixme">Fixme</h4> + +<p><s>Doing this is possible, but (afaik) there's no use-case, so it's just confusing the junior audience. The following code does exactly the same. There should at least be a note, that in theory you can do something like this, but there is no point in doing so.</s> The example is contrived, but imagine that [a, b, c] were the return value of some function. Then the utility is clear.</p> + +<p><s>Also, since <a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments">Function arguments</a> will never have named parameters (this is not Python), the statement "objects will soon be supported" is wrong. </s> The preceding example may be mixing up destructuring with rest parameters. Please see the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">page on destructuring assignment</a> for an example with object destructuring applied in the parameters area.</p> + +<pre class="brush: js">function f(a, b, c) { + return a + b + c +} + +f(1) // NaN (b and c are undefined) +f(1, 2, 3) // 6 +f(1, 2, 3, 4) // 6 (the fourth parameter is not ...) +</pre> +</div> + +<h2 id="Exemplos">Exemplos</h2> + +<p>In this example, the first argument is mapped to <code>a</code> and the second to <code>b</code>, so these named arguments are used like normal.</p> + +<p>However, the third argument, <code>manyMoreArgs</code>, will be an array that contains the 3<sup>rd</sup>, 4<sup>th</sup>, 5<sup>th</sup>, 6<sup>th</sup> ... <var>n</var><sup>th</sup> — as many arguments that the user includes.</p> + +<pre class="brush: js">function myFun(a, b, ...manyMoreArgs) { + console.log("a", a) + console.log("b", b) + console.log("manyMoreArgs", manyMoreArgs) +} + +myFun("one", "two", "three", "four", "five", "six") + +// a, one +// b, two +// manyMoreArgs, [three, four, five, six] +</pre> + +<p>Below... even though there is just one value, the last argument still gets put into an array.</p> + +<pre class="brush: js">// using the same function definition from example above + +myFun("one", "two", "three") + +// a, one +// b, two +// manyMoreArgs, [three]</pre> + +<p>Below, the third argument isn't provided, but <code>manyMoreArgs</code> is still an array (albeit an empty one).</p> + +<pre class="brush: js">// using the same function definition from example above + +myFun("one", "two") + +// a, one +// b, two +// manyMoreArgs, []</pre> + +<p>Since <code>theArgs</code> is an array, a count of its elements is given by the <code>length</code> property:</p> + +<pre class="brush: js">function fun1(...theArgs) { + console.log(theArgs.length) +} + +fun1() // 0 +fun1(5) // 1 +fun1(5, 6, 7) // 3 +</pre> + +<p>In the next example, a rest parameter is used to collect all parameters after the first into an array. Each one of them is then multiplied by the first parameter, and the array is returned:</p> + +<pre class="brush: js">function multiply(multiplier, ...theArgs) { + return theArgs.map(function(element) { + return multiplier * element + }) +} + +let arr = multiply(2, 1, 2, 3) +console.log(arr) // [2, 4, 6] +</pre> + +<p><code>Array</code> methods can be used on rest parameters, but not on the <code>arguments</code> object:</p> + +<pre class="brush: js">function sortRestArgs(...theArgs) { + let sortedArgs = theArgs.sort() + return sortedArgs +} + +console.log(sortRestArgs(5, 3, 7, 1)) // 1, 3, 5, 7 + +function sortArguments() { + let sortedArgs = arguments.sort() + return sortedArgs // this will never happen +} + + +console.log(sortArguments(5, 3, 7, 1)) +// throws a TypeError (arguments.sort is not a function) +</pre> + +<p>To use <code>Array</code> methods on the <code>arguments</code> object, it must be converted to a real array first.</p> + +<pre class="brush: js">function sortArguments() { + let args = Array.from(arguments) + let sortedArgs = args.sort() + return sortedArgs +} +console.log(sortArguments(5, 3, 7, 1)) // 1, 3, 5, 7 +</pre> + +<h2 id="Especificações">Especificações</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Especificação</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibildiade_de_navegador">Compatibildiade de navegador</h2> + + + +<p>{{Compat("javascript.functions.rest_parameters")}}</p> + +<h2 id="Consulte_também">Consulte também</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator" title="spread operator">Spread syntax</a> (also ‘<code>...</code>’)</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments" title="arguments">Arguments object</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" title="Array">Array</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions" title="Functions and function scope">Functions</a></li> + <li><a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters">Original proposal at ecmascript.org</a></li> + <li><a class="external" href="http://javascriptweblog.wordpress.com/2011/01/18/javascripts-arguments-object-and-beyond/">JavaScript arguments object and beyond</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destructuring assignment</a></li> +</ul> |