From 95aca4b4d8fa62815d4bd412fff1a364f842814a Mon Sep 17 00:00:00 2001 From: Ryan Johnson Date: Thu, 29 Apr 2021 16:16:42 -0700 Subject: remove retired locales (#699) --- .../reference/functions/arguments/index.html | 234 -------- .../reference/functions/arrow_functions/index.html | 426 ------------- .../functions/default_parameters/index.html | 198 ------- .../web/javascript/reference/functions/index.html | 657 --------------------- 4 files changed, 1515 deletions(-) delete mode 100644 files/vi/web/javascript/reference/functions/arguments/index.html delete mode 100644 files/vi/web/javascript/reference/functions/arrow_functions/index.html delete mode 100644 files/vi/web/javascript/reference/functions/default_parameters/index.html delete mode 100644 files/vi/web/javascript/reference/functions/index.html (limited to 'files/vi/web/javascript/reference/functions') diff --git a/files/vi/web/javascript/reference/functions/arguments/index.html b/files/vi/web/javascript/reference/functions/arguments/index.html deleted file mode 100644 index ffcb00b472..0000000000 --- a/files/vi/web/javascript/reference/functions/arguments/index.html +++ /dev/null @@ -1,234 +0,0 @@ ---- -title: The arguments object -slug: Web/JavaScript/Reference/Functions/arguments -translation_of: Web/JavaScript/Reference/Functions/arguments ---- -

{{JSSidebar("Functions")}}

- -

arguments là object giống Array khả truy cập bên trong hàm, chứa các giá trị của đối số truyền vào trong hàm đó.

- -
-

Ghi chú: Nếu bạn viết mã tương thích cho ES6, thì bạn nên tham khảo rest parameters.

-
- -
-

Ghi chú: “Giống Array” tức là arguments có thuộc tính {{jsxref("Functions/arguments/length", "length")}} và đánh chỉ mục từ không (0), nhưng nó không có phương thức dựng sẵn của {{JSxRef("Array")}} như {{jsxref("Array.forEach", "forEach()")}} và {{jsxref("Array.map", "map()")}}. Xem §Mô tả để biết thêm chi tiết.

-
- -
{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}
- - - -

Cú pháp

- -
arguments
- -

Mô tả

- -

Object arguments là biến cục bộ có sẵn cho mọi hàm không phải hàm mũi tên. Bạn có thể tham chiếu tới đối số của một hàm bên trong hàm đó bằng cách sử dụng object arguments. Nó chứa từng đối số mà hàm đó được gọi cùng, với chỉ mục bắt đầu từ 0.

- -

Chẳng hạn, nếu một hàm được truyền vào 3 đối số, bạn có thể truy cập nó theo cách sau:

- -
arguments[0] // đối số thứ nhất
-arguments[1] // đối số thứ hai
-arguments[2] // đối số thứ ba
-
- -

Mỗi đối số đều có thể thiết lập hoặc gán lại:

- -
arguments[1] = 'new value';
-
- -

Object arguments không phải là {{jsxref("Array")}}. Nó tương tự nhưng không có thuộc tính của Array ngoài {{jsxref("Array.length", "length")}}. Chẳng hạn, nó không có phương thức {{jsxref("Array.pop", "pop()")}}. Tuy nhiên, nó có thể ép kiểu về Array:

- -
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);
-
- -

Như có thể làm với mọi object giống-Array, bạn có thể dùng phương thức {{jsxref("Array.from()")}} của ES2015 hoặc cú pháp spread để ép kiểu arguments thành Array:

- -
var args = Array.from(arguments);
-var args = [...arguments];
-
- -

Object arguments có ích đối với hàm được truyền nhiều đối số hơn so với khởi tạo ban đầu. Kỹ thuật này có ích với hàm cần được truyền nhiều biến, như là {{jsxref("Math.min()")}}. Hàm ví dụ dưới đây chấp nhật mọi xâu ký tự và trả về xâu dài nhất:

- -
function longestString() {
-  var longest = '';
-  for (var i=0; i < arguments.length; i++) {
-    if (arguments[i].length > longest.length) {
-      longest = arguments[i];
-    }
-  }
-  return longest;
-}
-
- -

Bạn có thể dùng {{jsxref("Functions/arguments/length", "arguments.length")}} để đếm số lượng đối số được truyền vào khi hàm được gọi. Thay vì thế, nếu bạn muốn đếm số lượng tham số chính quy mà hàm chấp nhận khi khởi tạo, hãy tham khảo thuộc tính {{jsxref("Function.length", "length")}} của hàm.

- -

Sử dụng typeof với Arguments

- -

Toán tử {{jsxref("Operators/typeof", "typeof")}} trả về 'object' khi dùng với arguments

- -
console.log(typeof arguments); // 'object' 
- -

Kiểu của từng đối số có thể xác định lần lượt bằng cách chỉ đích danh trong object arguments:

- -
console.log(typeof arguments[0]); // trả về kiểu của đối số thứ nhất
- -

Thuộc tính

- -
-
{{jsxref("Functions/arguments/callee", "arguments.callee")}}
-
Tham chiếu tới hàm đang được thực thi sở hữu arguments.
-
{{jsxref("Functions/arguments/caller", "arguments.caller")}} {{Obsolete_Inline}}
-
Reference to the function that invoked the currently executing function.
-
{{jsxref("Functions/arguments/length", "arguments.length")}}
-
Số lượng đối số được truyền vào hàm.
-
{{jsxref("Functions/arguments/@@iterator", "arguments[@@iterator]")}}
-
Returns a new {{jsxref("Array/@@iterator", "Array iterator", "", 0)}} object that contains the values for each index in the arguments.
-
- -

Ví dụ

- -

Định nghĩa hàm nối xâu ký tự

- -

Ví dụ sau đây định nghĩa một hàm nối các xâu ký tự với nhau. Tham số chính quy mà hàm nhận là một xâu chứa các ký tự ngăn cách các xâu với nhau sau khi được nối.

- -
function myConcat(separator) {
-  var args = Array.prototype.slice.call(arguments, 1);
-  return args.join(separator);
-}
- -

Bạn có thể truyền vào bao nhiêu xâu ký tự tuỳ ý. Giá trị trả về là một xâu chứa tất cả các đối số được truyền vào:

- -
// trả về "red, orange, blue"
-myConcat(', ', 'red', 'orange', 'blue');
-
-// trả về "elephant; giraffe; lion; cheetah"
-myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
-
-// trả về "sage. basil. oregano. pepper. parsley"
-myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
- -

Định nghĩa hàm sinh danh sách HTML

- -

Ví dụ sau đây định nghĩa một hàm sinh ra một xâu ký tự chứa các thẻ HTML để tạo thành một danh sách. Tham số chính quy duy nhất mà hàm nhận là một ký tự như "u" nếu danh sách không có thứ tự (đánh dấu chấm), hay "o" nếu danh sách có thứ tự (đánh số). Hàm đó được định nghĩa như sau:

- -
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;
-}
- -

Bạn có thể truyền bao nhiêu đối số tuỳ ý, và nó sẽ thêm từng đối số vào danh sách có kiểu xác định trước. Chẳng hạn:

- -
var listHTML = list('u', 'One', 'Two', 'Three');
-
-/* listHTML is:
-"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
-*/
- -

Tham số rest, default và destructured

- -

Object arguments có thể dùng cùng lúc với các tham số như rest, default, và destructured.

- -
function foo(...args) {
-  return args;
-}
-foo(1, 2, 3); // [1,2,3]
-
- -

Tuy trong strict-mode, tham số rest, default, hoặc destructured parameters không can thiệp vào hành vi của object arguments, nhưng trong non-strict mode vẫn có không ít khác biệt.

- -

Nếu một hàm non-strict không chứa tham số rest, default, hay destructured, thì giá trị trong object arguments thay đổi đồng bộ với giá trị của tham số truyền vào. Hãy xem đoạn mã dưới đây:

- -
function func(a) {
-  arguments[0] = 99; // cập nhật arguments[0] cũng cập nhật a
-  console.log(a);
-}
-func(10); // 99
-
- -

- -
function func(a) {
-  a = 99; // cập nhật a cũng cập nhật arguments[0]
-  console.log(arguments[0]);
-}
-func(10); // 99
-
- -

Khi hàm non-strict chứa tham số rest, default hoặc destructured, thì giá trị trong object arguments không theo dõi giá trị của đối số. Thay vì vậy, chúng ánh xạ đến đối số truyền vào khi hàm được gọi:

- -
function func(a = 55) {
-  arguments[0] = 99; // updating arguments[0] does not also update a
-  console.log(a);
-}
-func(10); // 10
- -

- -
function func(a = 55) {
-  a = 99; // updating a does not also update arguments[0]
-  console.log(arguments[0]);
-}
-func(10); // 10
-
- -

- -
// An untracked default parameter
-function func(a = 55) {
-  console.log(arguments[0]);
-}
-func(); // undefined
- -

Đặc tả kĩ thuật

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Đặc tảTrạng tháiGhi chú
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES2015', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES2015')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
- -

Tương thích trình duyệt

- - - -

{{Compat("javascript.functions.arguments")}}

- -

Xem thêm

- - diff --git a/files/vi/web/javascript/reference/functions/arrow_functions/index.html b/files/vi/web/javascript/reference/functions/arrow_functions/index.html deleted file mode 100644 index 6da70e4205..0000000000 --- a/files/vi/web/javascript/reference/functions/arrow_functions/index.html +++ /dev/null @@ -1,426 +0,0 @@ ---- -title: Hàm mũi tên (hàm rút gọn) -slug: Web/JavaScript/Reference/Functions/Arrow_functions -translation_of: Web/JavaScript/Reference/Functions/Arrow_functions ---- -
{{jsSidebar("Functions")}}
- -

Biểu thức hàm mũi tên là một thay thế rút gọn cho hàm biểu thức truyền thống, nhưng bị hạn chế và không thể sử dụng trong mọi trường hợp.

- -

Sự khác biệt & Hạn chế:

- - - -

{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}

- -

So sánh hàm truyền thống và hàm mũi tên

- -

Hãy phân tách "hàm truyền thống" thành "hàm mũi tên" đơn giản nhất theo từng bước:
- LƯU Ý: Mỗi bước là một "hàm mũi tên" hợp lệ.

- -
// Hàm truyền thống
-function (a){
-  return a + 100;
-}
-
-// Phân rã thành hàm mũi tên
-
-// 1. Xóa từ khóa "function" và thay thế bằng mũi tên ở giữa đối số và dấu ngoặc nhọn bắt đầu nội dung hàm
-(a) => {
-  return a + 100;
-}
-
-// 2. Xóa dấu ngoặc nhọn và từ khóa "return" sự trả về đã bao hàm (mặc định) khi sử dụng hàm mũi tên.
-(a) => a + 100;
-
-// 3. Xóa luôn dấu ngoặc đơn của đối số
-a => a + 100;
- -

Như bạn thấy ở bên trên, dấu { ngoặc nhọn } và dấu (ngoặc tròn ở đối ố) và "return" là tùy chọn, nhưng đôi khi có thể bắt buộc phải có.

- -

Ví dụ, nếu bạn có nhiều đối số hoặc không có đối số, bạn cần phải thêm dấu ngoặc tròn vào xung quanh các đối số:

- -
// Hàm Truyền thống
-function (a, b){
-  return a + b + 100;
-}
-
-// Hàm mũi tên
-(a, b) => a + b + 100;
-
-// Hàm truyền thống (không đối số)
-let a = 4;
-let b = 2;
-function (){
-  return a + b + 100;
-}
-
-// Hàm mũi tên (không đối số)
-let a = 4;
-let b = 2;
-() => a + b + 100;
- -

Tương tự như vậy, nếu nội dung (body) hàm cần thêm nhiều dòng để xử lý thì bạn cần thêm vào dấu ngoặc nhọn CỘNG thêm "return" (hàm mũi tên không có kỳ diệu đến mức biết khi nào bạn muốn "return"):

- -
// Hàm truyền thống
-function (a, b){
-  let chuck = 42;
-  return a + b + chuck;
-}
-
-// Hàm mũi tên
-(a, b) => {
-  let chuck = 42;
-  return a + b + chuck;
-}
- -

Và cuối cùng, với các hàm được đặt tên chúng tôi xử lý các biểu thức mũi tên như các biến

- -
// Hàm truyền thống
-function bob (a){
-  return a + 100;
-}
-
-// Hàm mũi tên
-let bob = a => a + 100;
- -

Cú pháp

- -

Cú pháp cơ bản

- -
(param1, param2, …, paramN) => { statements }
-(param1, param2, …, paramN) => expression
-// tương đương với: (param1, param2, …, paramN) => { return expression; }
-
-// Dấu ngoặc đơn không bắt buộc khi chỉ có một tham số truyền vào:
-(singleParam) => { statements }
-singleParam => { statements }
-
-// Hàm khi không có tham số truyền vào bắt buộc phải là dấu ():
-() => { statements }
-() => expression // tương đương: () => { return expression; }
-
- -

Cú pháp nâng cao

- -
// Bên trong dấu ngoặc đơn là một đối tượng:
-params => ({foo: bar})
-
-// Rest parameters và default parameters được hỗ trợ
-(param1, param2, ...rest) => { statements }
-(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
-
-// Destructuring within the parameter list is also supported
-var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
-f();  // 6
-
- -

Chi tiết các ví dụ bạn có thể xem ở đây.

- -

Mô tả

- -

Xem thêm "ES6 Chuyên sâu: Những hàm arrow" trên hacks.mozilla.org.

- -

Two factors influenced the introduction of arrow functions: shorter functions and non-binding of this.

- -

Hàm ngắn

- -

Một vài ví dụ, cú pháp hàm rút gọn luôn được coder yêu thích, cùng so sánh:

- -
var materials = [
-  'Hydrogen',
-  'Helium',
-  'Lithium',
-  'Beryllium'
-];
-
-// thông thường
-var materialsLength1 = materials.map(function(material) {
-  return material.length;
-});
-
-// ngắn hơn (như mùa đông 5 độ vậy)
-var materialsLength2 = materials.map((material) => {
-  return material.length;
-});
-
-// ngắn hơn nữa (và -2 độ, bạn còn bao nhiêu cm ?)
-var materialsLength3 = materials.map(material => material.length);
-
- -

Không ràng buộc this

- -

Cho tới khi hàm rút gọn xuất hiện, mọi hàm mới đều tự định nghĩa giá trị this của riêng hàm (là object vừa được khởi tạo nếu dùng constructor, là undefined nếu đặt strict mode khi gọi hàm, là context object nếu hàm được gọi như một "object method", vân vân.). This trở nên khá khó chịu khi làm việc với phong cách lập trình hướng đối tượng.

- -
function Person() {
-  // constructor của Person() định nghĩa `this` như một biến.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // Khi dùng non-strict mode, hàm growUp() định nghĩa `this`
-    // như một đối tượng toàn cục, khác hoàn toàn so với `this`
-    // được định nghĩa bởi constructor của Person().
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

Theo ECMAScript 3/5, vấn đề của this có thể sửa được bằng cách gán this cho một biến gần nhất.

- -
function Person() {
-  var that = this;
-  that.age = 0;
-
-  setInterval(function growUp() {
-    // Hàm callback trỏ tới biến `that`với
-    // giá trị là đối tượng mong đợi.
-    that.age++;
-  }, 1000);
-}
- -

Nói cách khác, tạo ra một hàm ràng buộc để truyền giá trị của this vào hàm ràng buộc đích (chẳng hạn như hàm growUp() phía trên).

- -

Hàm rút gọn không tạo ra ngữ cảnh this của riêng hàm, thế nên this có ý nghĩa trong ngữ cảnh bọc quanh nó. Đoạn code phía dưới là một ví dụ:

- -
function Person(){
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this| ở đây trỏ tới đối tượng person
-  }, 1000);
-}
-
-var p = new Person();
- -

Mối liên hệ với strict mode

- -

Giả sử this bị bó buộc trong thân hàm, strict mode sẽ khiến cho this bị bỏ qua.

- -
var f = () => { 'use strict'; return this; };
-f() === window; // hoặc đối tượng toàn cục
- -

Các strict mode khác được áp dụng như bình thường.

- -

Gọi thông qua call hoặc apply

- -

Vì this không bị ràng buộc bên trong hàm rút gọn, các phương thức call() hoặc apply() chỉ có thể truyền tham số. this bị bỏ qua.

- -
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));         // Sẽ trả ra 2
-console.log(adder.addThruCall(1)); // Vẫn sẽ trả ra 2
- -

Không ràng buộc arguments

- -

Hàm rút gọn không ràng buộc arguments object. Do đó, trong ví dụ sau, arguments chỉ đơn giản là một tham chiếu đến đối tượng cùng tên trong phạm vi bao quanh:

- -
var arguments = 42;
-var arr = () => arguments;
-
-arr(); // 42
-
-function foo() {
-  var f = (i) => arguments[0] + i; // foo's implicit arguments binding
-  return f(2);
-}
-
-foo(1); // 3
- -

Trong nhiều trường hợp, sử dụng rest parameters là một cách thay thế tốt để dùng đối tượng arguments.

- -
function foo() {
-  var f = (...args) => args[0];
-  return f(2);
-}
-
-foo(1); // 2
- -

Dùng hàm rút gọn như một phương thức

- -

Như đã nói phía trên, biểu thức hàm rút gọn cực kì hợp với các hàm non-method. Hãy xem chuyện gì sẽ xảy ra khi ta dùng chúng như phương thức trong ví dụ bên dưới nhé:

- -
'use strict';
-var obj = {
-  i: 10,
-  b: () => console.log(this.i, this),
-  c: function() {
-    console.log(this.i, this);
-  }
-}
-obj.b(); // in ra undefined, Object {...}
-obj.c(); // in ra 10, Object {...}
- -

Hàm rút gọn không định nghĩa ("ràng buộc") this của hàm.  Một ví dụ khác đối với {{jsxref("Object.defineProperty()")}}:

- -
'use strict';
-var obj = {
-  a: 10
-};
-
-Object.defineProperty(obj, 'b', {
-  get: () => {
-    console.log(this.a, typeof this.a, this);
-    return this.a + 10; // đại diện cho đối tượng toàn cục 'Window', bởi vậy 'this.a' trả về 'undefined'
-  }
-});
-
- -

Dùng toán tử new

- -

Hàm rút gọn không thể dùng như phương thức khởi tạo và sẽ báo lỗi nếu dùng toán tử new.

- -
var Foo = () => {};
-var foo = new Foo(); // TypeError: Foo is not a constructor
- -

Dùng thuộc tính prototype

- -

Hàm rút gọn không có thuộc tính prototype.

- -
var Foo = () => {};
-console.log(Foo.prototype); // undefined
-
- -

Dùng từ khoá yield

- -

Từ khoá yield có thể sẽ không dùng được trong thân hàm rút gọn (trừ khi được gọi trong hàm lồng trong hàm rút gọn). Tức là, hàm rút gọn không thể dùng như là generator (hàm sinh).

- -

Phần thân hàm

- -

Hàm rút gọn vừa có thể có "concise body" hoặc dạng thường thấy "block body".

- -

Trong concise body, chỉ cần biểu thức, return sẽ được gán ngầm. Còn với block body, bạn phải có return.

- -
var func = x => x * x;                  // concise syntax, implied "return"
-var func = (x, y) => { return x + y; }; // with block body, explicit "return" needed
-
- -

Trả về object literals

- -

Không thể dùng cú pháp params => {object:literal} nếu muốn trả về object literal.

- -
var func = () => { foo: 1 };               // Calling func() returns undefined!
-var func = () => { foo: function() {} };   // SyntaxError: function statement requires a name
- -

Bởi vì đoạn code bên trong ({}) được phân giải thành một chuỗi các trình tự nối tiếp (ví dụ foo được coi như một nhãn, thay vì một key trong object literal).

- -

Thế nên hãy bao object literal trong ngoặc tròn.

- -
var func = () => ({foo: 1});
- -

Kí tự xuống dòng

- -

Hàm rút gọn không thể chứa bất cứ kí tự rút gọn nào giữa phần truyền tham số và dấu mũi tên.

- -
var func = ()
-           => 1; // SyntaxError: expected expression, got '=>'
- -

Parsing order

- -

Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.

- -
let callback;
-
-callback = callback || function() {}; // ok
-callback = callback || () => {};      // SyntaxError: invalid arrow-function arguments
-callback = callback || (() => {});    // ok
-
- -

Một số ví dụ khác

- -
// An empty arrow function returns undefined
-let empty = () => {};
-
-(() => 'foobar')(); // IIFE, returns "foobar"
-
-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);
-
- -

Đặc điểm kĩ thuật

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ESDraft')}}
- -

Tương thích trình duyệt

- -
{{Compat("javascript.functions.arrow_functions")}}
- -

Firefox-specific notes

- - - -

Tìm đọc

- - diff --git a/files/vi/web/javascript/reference/functions/default_parameters/index.html b/files/vi/web/javascript/reference/functions/default_parameters/index.html deleted file mode 100644 index 11ae77dab7..0000000000 --- a/files/vi/web/javascript/reference/functions/default_parameters/index.html +++ /dev/null @@ -1,198 +0,0 @@ ---- -title: Default parameters -slug: Web/JavaScript/Reference/Functions/Default_parameters -translation_of: Web/JavaScript/Reference/Functions/Default_parameters ---- -
{{jsSidebar("Functions")}}
- -

Các tham số của hàm mặc định cho phép khởi tạo với các giá trị mặc định khi không truyền giá trị vào đó.

- -
{{EmbedInteractiveExample("pages/js/functions-default.html")}}
- - - -

Cú pháp

- -
function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
-   statements
-}
-
- -

Mô tả

- -

Trong JavaScript, tham số của hàm mặc định {{jsxref("undefined")}}. Tuy nhiên, chúng thường hữu ích hơn khi tạo giá trị mặc định khác. 

- -

Trước đây, quy tắc chung khi tạo giá trị mặc định là kiểm tra các giá trị tham số trong thân hàm và gán vào tham số nếu nó không xác định.

- -

Trong ví dụ sau, nếu không cung cấp giá trị cho b khi gọi hàm multiply, b sẽ không xác định trong phép tính a * b và hàm multiply sẽ trả về NaN.

- -
function multiply(a, b) {
-  return a * b;
-}
-
-multiply(5, 2); // 10
-multiply(5);    // NaN !
-
- -

Để tránh điều này, ta sẽ dùng một dòng code xác định b=1 nếu hàm chỉ được gọi với 1 đối số.

- -
function multiply(a, b) {
-  b = (typeof b !== 'undefined') ?  b : 1;
-  return a * b;
-}
-
-multiply(5, 2); // 10
-multiply(5);    // 5
-
- -

Với các tham số mặc định trong ES2015, việc kiểm tra thân hàm không còn cần thiết. Bạn có thể gán 1 cho b ở đầu hàm:

- -
function multiply(a, b = 1) {
-  return a * b;
-}
-
-multiply(5, 2); // 10
-multiply(5);    // 5
-
- -

Ví dụ

- -

Truyền giá trị undefined với giá trị ảo

- -

Trong lời gọi thứ hai, ngay cả khi đối số thứ nhất không xác định (không phải null hay giá trị ảo), đối số num vẫn mặc định.

- -

function test(num = 1) { console.log(typeof num); } test(); // 'number' (num is set to 1) test(undefined); // 'number' (num is set to 1 too) // test with other falsy values: test(''); // 'string' (num is set to '') test(null); // 'object' (num is set to null)

- -

Xét tại thời điểm gọi

- -

Đối số mặc định được xét tại thời điểm gọi. Trong khi Python, một đối tượng mới được tạo ra mỗi khi hàm được gọi.

- -

function append(value, array = []) { array.push(value); return array; } append(1); //[1] append(2); //[2], not [1, 2]

- -

Áp dụng cho cả hàm và biến:

- -
function callSomething(thing = something()) {
- return thing;
-}
-
-let numberOfTimesCalled = 0;
-function something() {
-  numberOfTimesCalled += 1;
-  return numberOfTimesCalled;
-}
-
-callSomething(); // 1
-callSomething(); // 2
- -

Các tham số mặc định có sẵn cho các tham số mặc định sau:

- -

Các tham số được xác định trước (bên trái) có sẵn cho các tham số mặc định sau:

- -

function greet(name, greeting, message = greeting + ' ' + name) {     return [name, greeting, message]; } greet('David', 'Hi');  // ["David", "Hi", "Hi David"] greet('David', 'Hi', 'Happy Birthday!');  // ["David", "Hi", "Happy Birthday!"]

- -

This functionality can be aChức năng này sử dụng cho nhiều trường hợp xảy ra:

- -
function go() {
-  return ':P';
-}
-
-function withDefaults(a, b = 5, c = b, d = go(), e = this,
-                      f = arguments, g = this.value) {
-  return [a, b, c, d, e, f, g];
-}
-
-function withoutDefaults(a, b, c, d, e, f, g) {
-  switch (arguments.length) {
-    case 0:
-      a;
-    case 1:
-      b = 5;
-    case 2:
-      c = b;
-    case 3:
-      d = go();
-    case 4:
-      e = this;
-    case 5:
-      f = arguments;
-    case 6:
-      g = this.value;
-    default:
-  }
-  return [a, b, c, d, e, f, g];
-}
-
-withDefaults.call({value: '=^_^='});
-// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
-
-withoutDefaults.call({value: '=^_^='});
-// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="]
-
- -

Định nghĩa hàm trong thân hàm

- -

Giới thiệu trong Gecko 33 {{geckoRelease(33)}}. Các hàm được khai báo trong thân hàm không thể được tham chiếu bên trong với các tham số mặc định của hàm ngoài. Nếu bạn thử, {{jsxref("ReferenceError")}} sẽ bị loại bỏ. Các tham số mặc định luôn được thực thi trước, hàm khai báo bên trong thân hàm sẽ thực thi sau.

- -
// Doesn't work! Throws ReferenceError.
-function f(a = go()) {
-  function go() { return ':P'; }
-}
-
- -

Tham số không mặc định

- -

Trước Gecko 26 {{geckoRelease(26)}}, đoạn code sau cho kết quả {{jsxref("SyntaxError")}}. Sau đó được sửa lại {{bug(777060)}}. Các tham số vẫn xuất hiện từ trái qua phải, ghi đè lên các tham số mặc định kể cả các tham số sau không mặc định.

- -
function f(x = 1, y) {
-  return [x, y];
-}
-
-f(); // [1, undefined]
-f(2); // [2, undefined]
-
- -

Tham số bị hủy gán với giá trị mặc định

- -

Có thể dùng giá trị mặc định với kí hiệu destructuring assignment:

- -
function f([x, y] = [1, 2], {z: z} = {z: 3}) {
-  return x + y + z;
-}
-
-f(); // 6
- -

Đặc điểm

- - - - - - - - - - - - - - - - - - - -
Đặc điểmTrạng tháiGhi chú
{{SpecName('ES2015', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ES2015')}}Định nghĩa ban đầu
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ESDraft')}}
- -

Trình duyệt tương thích

- -
- - -

{{Compat("javascript.functions.default_parameters")}}

-
- -

Liên quan

- - diff --git a/files/vi/web/javascript/reference/functions/index.html b/files/vi/web/javascript/reference/functions/index.html deleted file mode 100644 index e7935d3318..0000000000 --- a/files/vi/web/javascript/reference/functions/index.html +++ /dev/null @@ -1,657 +0,0 @@ ---- -title: Functions -slug: Web/JavaScript/Reference/Functions -tags: - - Constructor - - Function - - Functions - - JavaScript - - NeedsTranslation - - Parameter - - TopicStub - - parameters -translation_of: Web/JavaScript/Reference/Functions ---- -
{{jsSidebar("Functions")}}
- -

Generally speaking, a function is a "subprogram" that can be called 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 function body. Values can be passed to a function, and the function will return a value.

- -

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 Function objects.

- -

For more examples and explanations, see also the JavaScript guide about functions.

- -

Description

- -

Every function in JavaScript is a Function object. See {{jsxref("Function")}} for information on properties and methods of Function objects.

- -

To return a value other than the default, a function must have a return statement that specifies the value to return. A function without a return statement will return a default value. In the case of a constructor called with the new keyword, the default value is the value of its this parameter. For all other functions, the default return value is {{jsxref("undefined")}}.

- -

The parameters of a function call are the function's arguments. Arguments are passed to functions by value. 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:

- -
/* 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);
-
- -

The this keyword does not refer to the currently executing function, so you must refer to Function objects by name, even within the function body.

- -

Defining functions

- -

There are several ways to define functions:

- -

The function declaration (function statement)

- -

There is a special syntax for declaring functions (see function statement for details):

- -
function name([param[, param[, ... param]]]) {
-   statements
-}
-
- -
-
name
-
The function name.
-
- -
-
param
-
The name of an argument to be passed to the function. A function can have up to 255 arguments.
-
- -
-
statements
-
The statements comprising the body of the function.
-
- -

The function expression (function expression)

- -

A function expression is similar to and has the same syntax as a function declaration (see function expression 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 hoisted onto the beginning of the scope, therefore they cannot be used before they appear in the code.

- -
function [name]([param[, param[, ... param]]]) {
-   statements
-}
-
- -
-
name
-
The function name. Can be omitted, in which case the function becomes known as an anonymous function.
-
- -
-
param
-
The name of an argument to be passed to the function. A function can have up to 255 arguments.
-
statements
-
The statements comprising the body of the function.
-
- -

Here is an example of an anonymous function expression (the name is not used):

- -
var myFunction = function() {
-    statements
-}
- -

It is also possible to provide a name inside the definition in order to create a named function expression:

- -
var myFunction = function namedFunction(){
-    statements
-}
-
- -

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.

- -

As we can see, both example do not start with the function keyword. Statements involving functions which do not start with function are function expressions.

- -

When function are used only once, a common pattern is an IIFE (Immediately Invokable Function Expressions).

- -
(function() {
-    statements
-})();
- -

IIFE are function expression that are invoked as soon as the function is declared.

- -

The generator function declaration (function* statement)

- -

There is a special syntax for generator function declarations (see {{jsxref('Statements/function*', 'function* statement')}} for details):

- -
function* name([param[, param[, ... param]]]) {
-   statements
-}
-
- -
-
name
-
The function name.
-
- -
-
param
-
The name of an argument to be passed to the function. A function can have up to 255 arguments.
-
- -
-
statements
-
The statements comprising the body of the function.
-
- -

The generator function expression (function* expression)

- -

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):

- -
function* [name]([param[, param[, ... param]]]) {
-   statements
-}
-
- -
-
name
-
The function name. Can be omitted, in which case the function becomes known as an anonymous function.
-
- -
-
param
-
The name of an argument to be passed to the function. A function can have up to 255 arguments.
-
statements
-
The statements comprising the body of the function.
-
- -

The arrow function expression (=>)

- -

An arrow function expression has a shorter syntax and lexically binds its this value (see arrow functions for details):

- -
([param[, param]]) => {
-   statements
-}
-
-param => expression
-
- -
-
param
-
The name of an argument. Zero arguments need to be indicated with ().  For only one argument, the parentheses are not required. (like foo => 1)
-
statements or expression
-
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.
-
- -

The Function constructor

- -
-

Note: Using the Function 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.

-
- -

As all other objects, {{jsxref("Function")}} objects can be created using the new operator:

- -
new Function (arg1, arg2, ... argN, functionBody)
-
- -
-
arg1, arg2, ... argN
-
Zero or more names to be used by the function as formal parameters. Each must be a proper JavaScript identifier.
-
- -
-
functionBody
-
A string containing the JavaScript statements comprising the function body.
-
- -

Invoking the Function constructor as a function (without using the new operator) has the same effect as invoking it as a constructor.

- -

The GeneratorFunction constructor

- -
-

Note: GeneratorFunction is not a global object, but could be obtained from generator function instance (see {{jsxref("GeneratorFunction")}} for more detail).

-
- -
-

Note: Using the GeneratorFunction 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.

-
- -

As all other objects, {{jsxref("GeneratorFunction")}} objects can be created using the new operator:

- -
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
-
- -
-
arg1, arg2, ... argN
-
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 "x", "theValue", or "a,b".
-
- -
-
functionBody
-
A string containing the JavaScript statements comprising the function definition.
-
- -

Invoking the Function constructor as a function (without using the new operator) has the same effect as invoking it as a constructor.

- -

Function parameters

- -

Default parameters

- -

Default function parameters allow formal parameters to be initialized with default values if no value or undefined is passed. For more details, see default parameters.

- -

Rest parameters

- -

The rest parameter syntax allows to represent an indefinite number of arguments as an array. For more details, see rest parameters.

- -

The arguments object

- -

You can refer to a function's arguments within the function by using the arguments object. See arguments.

- - - -

Defining method functions

- -

Getter and setter functions

- -

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.

- -
-
get
-
-

Binds an object property to a function that will be called when that property is looked up.

-
-
set
-
Binds an object property to a function to be called when there is an attempt to set that property.
-
- -

Method definition syntax

- -

Starting with ECMAScript 2015, you are able to define own methods in a shorter syntax, similar to the getters and setters. See method definitions for more information.

- -
var obj = {
-  foo() {},
-  bar() {}
-};
- -

Function constructor vs. function declaration vs. function expression

- -

Compare the following:

- -

A function defined with the Function constructor assigned to the variable multiply:

- -
var multiply = new Function('x', 'y', 'return x * y');
- -

A function declaration of a function named multiply:

- -
function multiply(x, y) {
-   return x * y;
-} // there is no semicolon here
-
- -

A function expression of an anonymous function assigned to the variable multiply:

- -
var multiply = function(x, y) {
-   return x * y;
-};
-
- -

A function expression of a function named func_name assigned to the variable multiply:

- -
var multiply = function func_name(x, y) {
-   return x * y;
-};
-
- -

Differences

- -

All do approximately the same thing, with a few subtle differences:

- -

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 undefined if the function name was previously declared via a var statement). For example:

- -
var y = function x() {};
-alert(x); // throws an error
-
- -

The function name also appears when the function is serialized via Function's toString method.

- -

On the other hand, the variable the function is assigned to is limited only by its scope, which is guaranteed to include the scope where the function is declared in.

- -

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:

- -

A function defined by 'new Function' does not have a function name. However, in the SpiderMonkey JavaScript engine, the serialized form of the function shows as if it has the name "anonymous". For example, alert(new Function()) outputs:

- -
function anonymous() {
-}
-
- -

Since the function actually does not have a name, anonymous is not a variable that can be accessed within the function. For example, the following would result in an error:

- -
var foo = new Function("alert(anonymous);");
-foo();
-
- -

Unlike functions defined by function expressions or by the Function constructor, a function defined by a function declaration can be used before the function declaration itself. For example:

- -
foo(); // alerts FOO!
-function foo() {
-   alert('FOO!');
-}
-
- -

A function defined by a function expression inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit).

- -

Functions defined by function expressions and function declarations are parsed only once, while those defined by the Function constructor are not. That is, the function body string passed to the Function 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 "new Function(...)". Therefore the Function constructor should generally be avoided whenever possible.

- -

It should be noted, however, that function expressions and function declarations nested within the function generated by parsing a Function constructor 's string aren't parsed repeatedly. For example:

- -
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.
- -

A function declaration is very easily (and often unintentionally) turned into a function expression. A function declaration ceases to be one when it either:

- - - -
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
-   }
-}
-
- -

Examples

- -
// 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() {}
-   }
-}
-
- -

Block-level functions

- -

In strict mode, starting with ES2015, functions inside blocks are now scoped to that block. Prior to ES2015, block-level functions were forbidden in strict mode.

- -
'use strict';
-
-function f() {
-  return 1;
-}
-
-{
-  function f() {
-    return 2;
-  }
-}
-
-f() === 1; // true
-
-// f() === 2 in non-strict mode
-
- -

Block-level functions in non-strict code

- -

In a word: Don't.

- -

In non-strict code, function declarations inside blocks behave strangely. For example:

- -
if (shouldDefineZero) {
-   function zero() {     // DANGER: compatibility risk
-      console.log("This is zero.");
-   }
-}
-
- -

ES2015 says that if shouldDefineZero is false, then zero 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 zero whether the block executed or not.

- -

In strict mode, all browsers that support ES2015 handle this the same way: zero is defined only if shouldDefineZero is true, and only in the scope of the if-block.

- -

A safer way to define functions conditionally is to assign a function expression to a variable:

- -
var zero;
-if (0) {
-   zero = function() {
-      console.log("This is zero.");
-   };
-}
-
- -

Examples

- -

Returning a formatted number

- -

The following function returns a string containing the formatted representation of a number padded with leading zeros.

- -
// 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;
-}
-
- -

The following statements call the padZeros function.

- -
var result;
-result = padZeros(42,4); // returns "0042"
-result = padZeros(42,2); // returns "42"
-result = padZeros(5,4);  // returns "0005"
-
- -

Determining whether a function exists

- -

You can determine whether a function exists by using the typeof operator. In the following example, a test is performed to determine if the window object has a property called noFunc that is a function. If so, it is used; otherwise some other action is taken.

- -
 if ('function' == typeof window.noFunc) {
-   // use noFunc()
- } else {
-   // do something else
- }
-
- -

Note that in the if test, a reference to noFunc is used—there are no brackets "()" after the function name so the actual function is not called.

- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}New: Arrow functions, Generator functions, default parameters, rest parameters.
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ESDraft')}} 
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Generator functions39{{CompatGeckoDesktop("26.0")}}{{CompatUnknown}}26{{CompatUnknown}}
Arrow functions{{CompatChrome(45.0)}}{{CompatGeckoDesktop("22.0")}}{{CompatNo}}{{CompatOpera(32)}}10
Block-level functions{{CompatUnknown}}{{CompatGeckoDesktop("46.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Generator functions{{CompatUnknown}}39{{CompatGeckoMobile("26.0")}}{{CompatUnknown}}26{{CompatUnknown}}
Arrow functions{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Block-level functions{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("46.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

See also

- - -- cgit v1.2.3-54-g00ecf