From da78a9e329e272dedb2400b79a3bdeebff387d47 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:17 -0500 Subject: initial commit --- .../functions/arguments/@@iterator/index.html | 78 +++ .../functions/arguments/callee/index.html | 203 +++++++ .../functions/arguments/caller/index.html | 93 ++++ .../reference/functions/arguments/index.html | 189 +++++++ .../functions/arguments/length/index.html | 74 +++ .../functions/default_parameters/index.html | 239 +++++++++ .../javascript/reference/functions/get/index.html | 179 +++++++ .../web/javascript/reference/functions/index.html | 596 +++++++++++++++++++++ .../functions/method_definitions/index.html | 230 ++++++++ .../reference/functions/rest_parameters/index.html | 223 ++++++++ .../javascript/reference/functions/set/index.html | 208 +++++++ .../index.html" | 465 ++++++++++++++++ 12 files changed, 2777 insertions(+) create mode 100644 files/ko/web/javascript/reference/functions/arguments/@@iterator/index.html create mode 100644 files/ko/web/javascript/reference/functions/arguments/callee/index.html create mode 100644 files/ko/web/javascript/reference/functions/arguments/caller/index.html create mode 100644 files/ko/web/javascript/reference/functions/arguments/index.html create mode 100644 files/ko/web/javascript/reference/functions/arguments/length/index.html create mode 100644 files/ko/web/javascript/reference/functions/default_parameters/index.html create mode 100644 files/ko/web/javascript/reference/functions/get/index.html create mode 100644 files/ko/web/javascript/reference/functions/index.html create mode 100644 files/ko/web/javascript/reference/functions/method_definitions/index.html create mode 100644 files/ko/web/javascript/reference/functions/rest_parameters/index.html create mode 100644 files/ko/web/javascript/reference/functions/set/index.html create mode 100644 "files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" (limited to 'files/ko/web/javascript/reference/functions') diff --git a/files/ko/web/javascript/reference/functions/arguments/@@iterator/index.html b/files/ko/web/javascript/reference/functions/arguments/@@iterator/index.html new file mode 100644 index 0000000000..454c8111b8 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/arguments/@@iterator/index.html @@ -0,0 +1,78 @@ +--- +title: 'arguments[@@iterator]()' +slug: Web/JavaScript/Reference/Functions/arguments/@@iterator +tags: + - Deprecated + - Functions + - JavaScript + - Property + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments/@@iterator +--- +
{{jsSidebar("Functions")}}
+ +

@@iterator 속성의 초기값은 {{jsxref("Array.prototype.values")}} 속성의 초기값과 같은 함수 객체입니다.

+ +

구문

+ +
arguments[Symbol.iterator]()
+ +

예제

+ +

for...of 반복문을 사용한 반복

+ +
function f() {
+  // 브라우저가 for...of 반복문과
+  // for 반복문 안의 let 범위의 변수를 지원해야 합니다.
+  for (let letter of arguments) {
+    console.log(letter);
+  }
+}
+f('w', 'y', 'k', 'o', 'p');
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-createunmappedargumentsobject', ' CreateUnmappedArgumentsObject')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ES6', '#sec-createmappedargumentsobject', ' CreateMappedArgumentsObject')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-createunmappedargumentsobject', 'CreateUnmappedArgumentsObject')}}{{Spec2('ESDraft')}} 
{{SpecName('ESDraft', '#sec-createmappedargumentsobject', 'CreateMappedArgumentsObject')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ +
+ + +

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

+
+ +

같이 보기

+ + diff --git a/files/ko/web/javascript/reference/functions/arguments/callee/index.html b/files/ko/web/javascript/reference/functions/arguments/callee/index.html new file mode 100644 index 0000000000..13ab0c948d --- /dev/null +++ b/files/ko/web/javascript/reference/functions/arguments/callee/index.html @@ -0,0 +1,203 @@ +--- +title: arguments.callee +slug: Web/JavaScript/Reference/Functions/arguments/callee +tags: + - Deprecated + - Functions + - JavaScript + - Property + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments/callee +--- +
{{jsSidebar("Functions")}}
+ +

arguments.callee 속성(property)은 현재 실행 중인 함수를 포함합니다.

+ +

설명

+ +

calleearguments 객체의 속성입니다. 그 함수의 몸통(body) 내에서 현재 실행 중인 함수를 참조하는 데 쓰일 수 있습니다. 이는 함수의 이름을 알 수 없는 경우에 유용합니다, 가령 이름 없는 함수 식(또한 "익명 함수"라 함) 내에서.

+ +
경고: ECMAScript 제5판(ES5) 은 엄격 모드에서 arguments.callee()의 사용을 금합니다. function 식(expression)에 이름을 주거나 함수 자체를 호출해야 하는 곳에 function 선언을 사용하여 arguments.callee() 사용을 피하세요.
+ +

arguments.callee는 왜 ES5 엄격 모드에서 제거되었나요?

+ +

(olliej의 Stack Overflow 답변에서 고쳐씀)

+ +

초기 버전 JavaScript는 유명(named) 함수 식을 허용하지 않습니다. 그리고 이 때문에 재귀(recursive) 함수 식을 만들 수 없습니다.

+ +

예를 들어, 이 구문은 작동됩니다:

+ +
function factorial (n) {
+    return !(n > 1) ? 1 : factorial(n - 1) * n;
+}
+
+[1,2,3,4,5].map(factorial);
+ +

하지만 다음은:

+ +
[1,2,3,4,5].map(function (n) {
+    return !(n > 1) ? 1 : /* what goes here? */ (n - 1) * n;
+});
+ +

아닙니다. 이를 우회하기 위해 arguments.callee가 추가되었고 이와 같이 할 수 있습니다

+ +
[1,2,3,4,5].map(function (n) {
+    return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
+});
+ +

그러나, 이는 실로 정말 나쁜 해결책이었습니다. 이는 (다른 arguments, calleecaller 문제와 함께) 일반적인 경우에 인라인 및 tail 재귀를 불가능케 하기에 (tracing 등을 통해 선택한 경우에 그것을 달성할 수 있지만 최고의 코드는 검사가 달리 필요하지 않기에 차선입니다.) 다른 주요 문제는 그 재귀 호출이 다른 this 값을 갖는 것입니다. 가령:

+ +
var global = this;
+
+var sillyFunction = function (recursed) {
+    if (!recursed) { return arguments.callee(true); }
+    if (this !== global) {
+        alert("This is: " + this);
+    } else {
+        alert("This is the global");
+    }
+}
+
+sillyFunction();
+ +

ECMAScript 3은 유명(named) 함수 식을 허용해서 이 문제를 해결했습니다. 예를 들면:

+ +
[1,2,3,4,5].map(function factorial (n) {
+    return !(n > 1) ? 1 : factorial(n-1)*n;
+});
+ +

이는 많은 이점이 있습니다:

+ + + +

사라지게 됐던 또 다른 기능은 arguments.callee.caller 또는 더 명확하게 Function.caller였습니다. 이는 왜일까요? 자, 어느 시점에서든 당신은 모든 함수의 스택 상 가장 깊은 caller를 찾을 수 있고 위에서 말했듯이 호출 스택 보기는 한 가지 주요 효과가 있습니다: 이는 큰 수의 최적화를 불가능 또는 훨씬 훨씬 더 어렵게 합니다. 예를 들어, 함수 f가 익명(unknown) 함수를 호출하지 않음을 보장할 수 없는 경우, f를 인라인하는 게 가능하지 않습니다. 원래 사소하게 인라인 가능했을 지도 모를 모든 호출 사이트가 다수의 guard를 축적함을 뜻합니다:

+ +
function f (a, b, c, d, e) { return a ? b * c : d * e; }
+ +

JavaScript 인터프리터가 제공된 모든 인수가 호출이 행해진 그 시점에 숫자임을 보장할 수 없다면, 인라인된 코드 앞에 모든 인수에 대한 검사 삽입이 필요합니다. 그렇지 않으면 그 함수를 인라인할 수 없습니다. 이제 이 특정한 경우에 스마트 인터프리터는 더 최적이고 사용되지 않을 값은 확인하지 않을 검사를 재배열할 수 있어야 합니다. 그러나 많은 경우에 그건 그냥 가능하지 않고 그러므로 인라인은 불가능하게 됩니다.

+ +

+ +

익명 재귀 함수에서 arguments.callee 사용하기

+ +

재귀 함수는 자신을 참조할 수 있어야 합니다. 보통, 함수는 그 이름으로 자신을 참조합니다. 그러나, 익명 함수(함수 식 또는 Function 생성자로 생성될 수 있는)는 이름이 없습니다. 그러므로 그를 참조하는 액세스 가능한 변수가 없는 경우, 함수가 자신을 참조할 수 있는 유일한 방법은 arguments.callee에 의해서입니다.

+ +

다음 예는 차례로 팩토리얼 함수를 정의하고 반환하는 함수를 정의합니다. 이 예는 매우 실용적이지 않고 같은 결과가 유명 함수 식으로 달성될 수 없는 경우가 거의 없습니다.

+ +
function create() {
+   return function(n) {
+      if (n <= 1)
+         return 1;
+      return n * arguments.callee(n - 1);
+   };
+}
+
+var result = create()(5); // 반환값 120 (5 * 4 * 3 * 2 * 1)
+ +

좋은 대안 없는 arguments.callee의 사용

+ +

그러나, 다음과 같은 경우에는 arguments.callee에 대안이 없습니다. 그래서 그 사라짐(deprecation)은 버그가 될 수 있습니다 ({{Bug("725398")}} 참조):

+ +
function createPerson (sIdentity) {
+    var oPerson = new Function("alert(arguments.callee.identity);");
+    oPerson.identity = sIdentity;
+    return oPerson;
+}
+
+var john = createPerson("John Smith");
+
+john();
+ +

스펙

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
스펙상태설명
{{SpecName('ES1')}}{{Spec2('ES1')}}초기 정의. JavaScript 1.2에서 구현됨
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

참조

+ + diff --git a/files/ko/web/javascript/reference/functions/arguments/caller/index.html b/files/ko/web/javascript/reference/functions/arguments/caller/index.html new file mode 100644 index 0000000000..bcdc54c7dc --- /dev/null +++ b/files/ko/web/javascript/reference/functions/arguments/caller/index.html @@ -0,0 +1,93 @@ +--- +title: arguments.caller +slug: Web/JavaScript/Reference/Functions/arguments/caller +translation_of: Archive/Web/JavaScript/arguments.caller +--- +
{{jsSidebar("Functions")}}
+ +

이전의 arguments.caller 속성은 현재 실행한 함수를 적용하여 제공했었습니다. 이 속성은 삭제되었으며 더 이상 작동하지 않습니다.

+ +

설명

+ +

이 속성은 더 이상 이용할 수 없습니다. 하지만 {{jsxref("Function.caller")}} 는 사용할 수 있습니다.

+ +
function whoCalled() {
+   if (whoCalled.caller == null)
+      console.log('I was called from the global scope.');
+   else
+      console.log(whoCalled.caller + ' called me!');
+}
+ +

+ +

다음의 코드는 함수 내에서 arguments.caller 값을 확인하기 위해 사용되었지만, 더 이상 작동하지 않습니다.

+ +
function whoCalled() {
+   if (arguments.caller == null)
+      console.log('I was called from the global scope.');
+   else
+      console.log(arguments.caller + ' called me!');
+}
+
+ +

스펙

+ +

초기 정의된 부분이 아닙니다. JavaScript 1.1에서 구현되었으며, 잠재적인 보안 취약의 우려로 ({{bug(7224)}}) 삭제되었습니다.

+ +

브라우저 호환성

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

참조

+ + diff --git a/files/ko/web/javascript/reference/functions/arguments/index.html b/files/ko/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..98b5f1385b --- /dev/null +++ b/files/ko/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,189 @@ +--- +title: arguments 객체 +slug: Web/JavaScript/Reference/Functions/arguments +tags: + - Functions + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +
+
{{jsSidebar("Functions")}}
+
+ +

arguments 객체는 함수에 전달된 인수에 해당하는 Array 형태의 객체입니다.

+ +
+

Note: ES6 호환 코드를 작성 중이라면 되도록 나머지 매개변수 구문을 사용해야 합니다.

+
+ +
+

참고: "Array 형태"란 arguments가 {{jsxref("Array.length", "length")}} 속성과 더불어 0부터 인덱스 된 다른 속성을 가지고 있지만, {{jsxref("Array")}}의 {{jsxref("Array.prototype.forEach()", "forEach")}}, {{jsxref("Array.prototype.map()", "map")}}과 같은 내장 메서드를 가지고 있지 않다는 뜻입니다.

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

구문

+ +
arguments
+ +

설명

+ +

arguments 객체는 모든 함수 내에서 이용 가능한 지역 변수입니다. arguments 객체를 사용하여 함수 내에서 모든 인수를 참조할 수 있으며, 호출할 때 제공한 인수 각각에 대한 항목을 갖고 있습니다. 항목의 인덱스는 0부터 시작합니다.

+ +

예를 들어, 함수가 세 개의 인수를 받은 경우 다음과 같이 접근할 수 있습니다.

+ +
arguments[0]
+arguments[1]
+arguments[2]
+
+ +

각 인수를 설정하거나 재할당할 수도 있습니다.

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

arguments 객체는 {{jsxref("Array")}}가 아닙니다. Array와 비슷하지만, {{jsxref("Array.prototype.length", "length")}} 빼고는 {{jsxref("Array.prototype.pop", "pop()")}}과 같은 어떤 Array 속성도 없습니다. 그러나 실제 Array로 변환할 수 있습니다:

+ +
var args = Array.prototype.slice.call(arguments);
+var args = [].slice.call(arguments);
+
+ +

arguments를 실제 Array로 변환하기 위해 ES2015의 {{jsxref("Array.from()")}} 메서드 또는 전개 연산자를 사용할 수도 있습니다.

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

당신이 형식상 받기로 선언된 것보다 많은 인수로 함수를 호출하는 경우 arguments 객체를 사용할 수 있습니다. 이 기법은 가변 인수가 전달될 수 있는 함수에 유용합니다. 함수에 전달된 인수의 수를 결정하기 위해 arguments.length를 쓰세요, 그 뒤에 arguments 객체를 사용하여 각 인수를 처리하세요. 함수 signature에 매개변수의 수를 결정하기 위해서는, Function.length 속성을 쓰세요.

+ +

속성

+ +
+
arguments.callee
+
현재 실행 중인 함수를 가리킵니다.
+
arguments.caller {{ Obsolete_inline() }}
+
현재 실행 중인 함수를 호출한 함수를 가리킵니다.
+
arguments.length
+
함수에 전달된 인수의 수를 가리킵니다.
+
arguments[@@iterator]
+
arguments의 각 인덱스 값을 포함하는 새로운 Array Iterator 객체를 반환합니다.
+
+ +

예제

+ +

여러 문자열을 연결하는 함수 정의하기

+ +

이 예는 여러 문자열을 연결하는 함수를 정의합니다. 함수의 유일한 형식 인수는 연결할 항목을 구분하는 문자를 지정하는 문자열입니다. 함수는 다음과 같이 정의됩니다:

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

이 함수에 인수를 얼마든지 전달할 수 있으며 리스트 내 항목처럼 각 인수를 사용하여 리스트를 만듭니다.

+ +
// "red, orange, blue" 반환
+myConcat(", ", "red", "orange", "blue");
+
+// "elephant; giraffe; lion; cheetah" 반환
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// "sage. basil. oregano. pepper. parsley" 반환
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+ +

HTML 리스트를 만드는 함수 정의하기

+ +

이 예는 리스트 HTML을 포함하는 문자열을 만드는 함수를 정의합니다. 함수의 유일한 형식 인수는 리스트가 정렬되지 않은(bulluet(글 머리 기호)가 붙는) 경우 "u" 또는 정렬된(번호가 매겨진) 경우 "o"인 문자열입니다. 함수는 다음과 같이 정의됩니다:

+ +
function list(type) {
+  var result = "<" + type + "l><li>";
+  var args = Array.prototype.slice.call(arguments, 1);
+  result += args.join("</li><li>");
+  result += "</li></" + type + "l>"; // end list
+
+  return result;
+}
+ +

이 함수에 인수를 얼마든지 전달할 수 있고, 표시된 유형의 리스트에 항목으로 각 인수를 추가합니다. 예를 들면:

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

나머지, 기본 및 비구조화된 매개변수

+ +

arguments 객체는 나머지 매개변수, 기본 매개변수 또는 비구조화된 매개변수와 함께 사용될 수 있습니다.

+ +
function foo(...args) {
+  return arguments;
+}
+foo(1, 2, 3); // { "0": 1, "1": 2, "2": 3 }
+
+ +

그러나, 비엄격 함수에서는 mapped arguments 객체는 함수가 어떤 나머지 매개변수, 기본 매개변수 또는 비구조화된 매개변수든 포함하지 않는 경우에만 제공됩니다. 예를 들어, 기본 매개변수를 사용하는 다음 함수에서는, 100 대신에 10이 반환됩니다:

+ +
function bar(a=1) {
+  arguments[0] = 100;
+  return a;
+}
+bar(10); // 10
+
+ +

이 예에서, 어떤 나머지 매개변수, 기본 매개변수 또는 비구조화된 매개변수가 없는 경우에는, 100이 반환됩니다:

+ +
function zoo(a) {
+  arguments[0] = 100;
+  return a;
+}
+zoo(10); // 100
+
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
스펙상태설명
{{SpecName('ES1')}}{{Spec2('ES1')}}초기 정의. JavaScript 1.1에서 구현됨
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ +

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

+ +

같이 보기

+ + diff --git a/files/ko/web/javascript/reference/functions/arguments/length/index.html b/files/ko/web/javascript/reference/functions/arguments/length/index.html new file mode 100644 index 0000000000..d8ea3f0da4 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/arguments/length/index.html @@ -0,0 +1,74 @@ +--- +title: arguments.length +slug: Web/JavaScript/Reference/Functions/arguments/length +translation_of: Web/JavaScript/Reference/Functions/arguments/length +--- +
{{jsSidebar("Functions")}}
+ +

arguments.length 속성은 함수에 전달된 인수의 수를 포함하고 있습니다.

+ +

구문

+ +
arguments.length
+ +

설명

+ +

arguments.length 속성은 실제로 함수에 전달된 arguments 의 수를 제공합니다. 이것은 정의된 매개변수의 수보다 작을 수도 클 수도 있습니다. ({{jsxref("Function.length")}} 보기).

+ +

예제

+ +

arguments.length 사용하기

+ +

이 예시에서는 둘 또는 그 이상의 수를 더할 수 있는 함수를 정의합니다.

+ +
function adder(base /*, n2, ... */) {
+  base = Number(base);
+  for (var i = 1; i < arguments.length; i++) {
+    base += Number(arguments[i]);
+  }
+  return base;
+}
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}초기 정의. JavaScript 1.1에서 구현됨.
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ +

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

+ +

같이 보기

+ + diff --git a/files/ko/web/javascript/reference/functions/default_parameters/index.html b/files/ko/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..2783b65844 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,239 @@ +--- +title: 기본값 매개변수 +slug: Web/JavaScript/Reference/Functions/Default_parameters +tags: + - ECMAScript2015 + - ECMAScript6 + - Functions + - JavaScript + - 기본값 매개변수 +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +
{{jsSidebar("Functions")}}
+ +

 기본값 함수 매개변수 (default function parameter)를 사용하면 값이 없거나 undefined가 전달될 경우 이름붙은 매개변수를 기본값으로 초기화할 수 있습니다.

+ +

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

+ + + +

구문

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

설명

+ +

JavaScript에서, 함수의 매개변수는 {{jsxref("undefined")}}가 기본입니다. 그러나, 일부 상황에서는 다른 기본 값을 설정하는 것이 유용할 수 있습니다. 이때가 바로 기본값 매개변수 가 필요할 때 입니다.

+ +

과거에 기본값 설정을 위한 일반적인 방법은 함수 내부(body)에서 매개변수 값을 검사해 undefined인 경우 값을 할당하는 것이었습니다.

+ +

다음 예제에서, multiply호출시 b에 할당된  값이 없다면, b 값은 a*b를 평가할 때 undefined일 거고 multiply 호출은 NaN이 반환됩니다. 

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

이를 방지하기 위해서, 아래 두번째 줄과 같이  multiply 함수가 오직 한 개의 인수만 있다면  b를  1로 설정하는 방식을 사용하곤 했습니다.

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

ES2015의 기본값 매개변수로 함수 내부 에서의 검사는 더 이상 필요치 않습니다. 이제, 간단히 함수 머리(head)에서 b의 기본값으로 1 로 설정할 수 있습니다:

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

예제

+ +

undefined vs. 다른 거짓같은 값(falsy values) 전달하기

+ +

아래 예제중 두 번째 호출에서, 설사 두 번째 인수를 호출할 때 명시해서 undefined (null 혹은 {{glossary("falsy")}} 값이 아니긴 하지만 )로 설정하더라도 , num 인수의 값은 여전히 기본값입니다.

+ +
function test(num = 1) {
+  console.log(typeof num)
+}
+
+test()            // 'number' (num 은 1로 설정됨)
+test(undefined)   // 'number' (num 이 역시 1로 설정됨)
+
+// 다른 falsy values로 테스트 하기:
+test('')          // 'string' (num 은 ''로 설정됨)
+test(null)        // 'object' (num 은 null로 설정됨)
+
+ +

호출 시 평가

+ +

기본 인수는 호출 시 에 평가됩니다, 그래서 Python의 경우 와는 달리, 함수가 호출될 때마다 새로운 객체가 생성됩니다.

+ +
function append(value, array = []) {
+  array.push(value)
+  return array
+}
+
+append(1)  // [1]
+append(2)  // [2], [1, 2]가 아니라
+
+
+ +

이는 심지어 함수 및 변수에도 적용됩니다:

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

앞쪽 매개변수는 뒷쪽의 매개변수 기본값에 사용할 수 있습니다

+ +

매개 변수가 여러개일 때 앞쪽에( 왼쪽 부분) 정의된 매개변수는 뒷쪽에 정의된 매개변수의 기본값에  바로 사용할 수 있습니다.

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

이 기능은,  얼마나 많은 경계 조건(edge case)를 다룰수 있는지 보여주는, 아래 예제로 거의 설명 가능합니다.

+ +
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, "=^_^="]
+
+ +

유효범위 효과 (Scope Effects)

+ +

한개 이상의 매개변수에 기본값이 지정되면 특별히 매개변수 목록내의 식별자들(identifiers) 대상으로, 두번째 스코프 (Environment Record) 가 생성됩니다.

+ +

이 말은 함수 내부에 선언된 함수와 변수들은 매개변수 기본값 초기화시에 참조할 수  없다는 말입니다; 그렇게 하려고 하면 실행시간 에러인 {{jsxref("ReferenceError")}} 를 유발합니다.

+ +

이 말은 또한 함수 내부에서 var 로 선언된 변수는 동일한 이름을 가진 매개변수를 가리게 되는, 중첩 var 선언 으로 인한 일반적인 동작이 일어나지 않는다는 말입니다.

+ +

아래 함수는 호출되면 ReferenceError 를 발생시킵니다. 매개변수 기본값이 함수 내부의 자식 유효범위를 참조할 수 없기 때문입니다.

+ +
function f(a = go()) { // `f`가 호출 되면 `ReferenceError` 발생
+  function go() { return ':P' }
+}
+ +

...그리고 아래 함수는 undefined 를 프린트 하는데,  var a 가 함수 내부 대상의 유효범위내에서만 효과를 가지기 때문입니다. ( 매개변수 목록이 대상인 부모 스코프가 아니라)

+ +
function f(a, b = () => console.log(a)) {
+  var a = 1
+  b() // `undefined`를 인쇄하는데, 매개변수 기본값이 자체 스코프에 있기 때문입니다
+} 
+ +

기본값 매개변수 뒤쪽의 기본값 없는 매개변수

+ +

매개변수는 여전히 왼쪽에서 오른쪽으로 설정됩니다. 아래 예제에서 뒷쪽에 기본값이 없는 매개변수가 있지만 기본값 매개변수를 덮어씁니다.

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

기본값 할당 있는 해체된 매개변수

+ +

기본값 할당을 {{jsxref("Operators/Destructuring_assignment", "destructuring assignment", "", 1)}} 표기와 함께 사용할 수 있습니다:

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

스펙

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}
+ +

브라우저 호환성

+ + + +

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

+ +

참조

+ + diff --git a/files/ko/web/javascript/reference/functions/get/index.html b/files/ko/web/javascript/reference/functions/get/index.html new file mode 100644 index 0000000000..fb64206dff --- /dev/null +++ b/files/ko/web/javascript/reference/functions/get/index.html @@ -0,0 +1,179 @@ +--- +title: getter +slug: Web/JavaScript/Reference/Functions/get +tags: + - 자바스크립트 + - 함수 +translation_of: Web/JavaScript/Reference/Functions/get +--- +
{{jsSidebar("Functions")}}
+ +

get 구문은 객체의 프로퍼티를 그 프로퍼티를 가져올 때 호출되는 함수로 바인딩합니다.

+ +

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

+ + + +

구문

+ +
{get prop() { ... } } {get [expression]() { ... } }
+ +

매개변수

+ +
+
prop
+
주어진 함수를 바인딩할 프로퍼티의 이름입니다.
+
expression
+
ECMAScript 2015가 도입되면서, 함수의 이름을 계산하기 위해 표현식을 사용할 수 있습니다.
+
+ +

설명

+ +

어떤 프로퍼티에 접근할 때마다 그 값을 계산하도록 해야 하거나, 내부 변수의 상태를 명시적인 함수 호출 없이 보여주고 싶을 때, JavaScript의 getter를 이용할 수 있습니다. getter가 바인딩된 프로퍼티는 동시에 실제 값을 가질 수는 없지만, getter와 setter를 동시에 바인딩해 일종의 유사 프로퍼티(pseudo-property)를 만들 수는 있습니다.

+ +

get 구문을 이용할 때는 다음을 유의하세요.

+ +
+ +
+ +

getter는 delete 연산자를 이용해 삭제할 수 있습니다.

+ +

+ +

getter를 객체 초기자에서 정의하기

+ +

객체 obj에 유사 프로퍼티 latest를 생성합니다. latest는 배열 log의 마지막 요소를 반환합니다.

+ +
var obj = {
+  log: ['example','test'],
+  get latest() {
+    if (this.log.length == 0) return undefined;
+    return this.log[this.log.length - 1];
+  }
+}
+console.log(obj.latest); // "test".
+ +

latest에 어떤 값을 할당하려고 시도해도 그 값이 바뀌지 않는다는 점을 유의하세요.

+ +

delete연산자를 이용해 getter 삭제하기

+ +

getter를 삭제하고 싶다면, delete를 이용하면 됩니다.

+ +
delete obj.latest;
+
+ +

defineProperty를 이용해 이미 존재하는 객체에 getter 정의하기

+ +

이미 존재하는 객체에 getter를 추가하고자 한다면, {{jsxref("Object.defineProperty()")}}를 이용하면 됩니다.

+ +
var o = { a:0 }
+
+Object.defineProperty(o, "b", { get: function () { return this.a + 1; } });
+
+console.log(o.b) // getter를 실행합니다. a + 1 (= 1)이 반환됩니다.
+ +

계산된 (computed) 프로퍼티 이름

+ +
var expr = "foo";
+
+var obj = {
+  get [expr]() { return "bar"; }
+};
+
+console.log(obj.foo); // "bar"
+ +

똑똑한(Smart) / 스스로 덮어쓰는(self-overwriting) / 느긋한(lazy) getter

+ +

Getter는 객체에 프로퍼티를 정의할 수 있도록 하지만, 그 프로퍼티에 접근하기 전까지는 값을 계산하지 않습니다. getter는 값을 계산하는 비용을 실제 값이 필요할 때까지 미루며, 그 값이 필요없다면 계산 비용도 들지 않습니다.

+ +

또다른 최적화 기법으로는 계산 미루기와 함께 프로퍼티 값을 나중에 접근하기 위해 캐싱하는 것이 있습니다. 이를 똑똑한(smart), 혹은 메모화된(memoized) getter라고 부릅니다. 값은 getter가 호출될 때 처음 계산되며, 캐싱됩니다. 이후의 호출에는 다시 계산하지 않고 이 캐시값을 반환합니다. 이는 다음과 같은 상황에 유용합니다.

+ + + +

똑똑한 getter는 값을 다시 계산하지 않기 때문에, 값의 변경이 예상되는 경우에는 똑똑한 getter를 이용해서는 안 됩니다.

+ +

다음 예제에서, 객체는 원래 프로퍼티로 getter를 가집니다. 프로퍼티를 가져올 때, getter는 삭제되며 대신 명시적인 값이 저장됩니다. 최종적으로 값을 반환합니다.

+ +
get notifier() {
+  delete this.notifier;
+  return this.notifier = document.getElementById("bookmarked-notification-anchor");
+},
+ +

Firefox 코드의 경우,  defineLazyGetter() 함수를 정의하고 있는 XPCOMUtils.jsm 모듈을 참조하세요.

+ +

get Vs. defineProperty

+ +

While using the get 키워드와 {{jsxref("Object.defineProperty()")}}를 사용하면 비슷한 결과를 얻지만, {{jsxref("classes")}}에서 사용되는 두 가지 경우에는 미묘한 차이가 있습니다.

+ +

get을 사용할 때 속성은 {{jsxref("Object.defineProperty()")}} 를 사용하는 동안 객체의 프로토 타입에 정의 될 것이고, 속성은 그것이 적용되는 인스턴스에 정의 될 것입니다.

+ +
class Example {
+  get hello() {
+    return 'world';
+  }
+}
+
+const obj = new Example();
+console.log(obj.hello);
+// "world"
+console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
+// undefined
+console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'hello'));
+// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
+ +

 

+ +

스펙

+ + + + + + + + + + + + + + + + + + + + + + + + +
스펙상태설명
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}최초로 정의되었습니다.
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}계산된 프로퍼티 이름이 추가되었습니다.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ + + +

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

+ +

 

+ +

참조

+ + diff --git a/files/ko/web/javascript/reference/functions/index.html b/files/ko/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..2052b67a93 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/index.html @@ -0,0 +1,596 @@ +--- +title: 함수 +slug: Web/JavaScript/Reference/Functions +tags: + - 생성자 + - 인자 + - 파라미터 + - 함수 +translation_of: Web/JavaScript/Reference/Functions +--- +
{{jsSidebar("Functions")}}
+ +

일반적으로, 함수는 함수 외부 (또는 재귀(recursion)의 경우엔 내부) 코드에 의해 호출될 수 있는 "하위프로그램"입니다. 프로그램 그 자체처럼, 함수는 함수 몸통(function body)이라고 하는 일련의 구문(statement)으로 구성됩니다. 값은 함수에 전달될 수 있고 함수는 값을 반환합니다.

+ +

JavaScript에서, 함수는 다른 객체처럼 속성 및 메서드를 가질 수 있기에 일급(first-class) 객체입니다. 다른 객체와 함수를 구별하는 것은 함수는 호출될 수 있다는 것입니다. 간단히 말해, 함수는 Function 객체입니다.

+ +

더 많은 예제와 설명은, JavaScript 함수 안내서를 참조하세요.

+ +

설명

+ +

JavaScript에서 모든 함수는 Function 객체입니다. Function 객체의 속성(property) 및 메서드에 관한 정보는 {{jsxref("Function")}} 참조.

+ +

기본값 이외의 값을 반환하려면, 함수는 반환할 값을 지정하는 return 문이 있어야 합니다. return 문이 없는 함수는 기본값을 반환합니다. new 키워드로 호출되는 생성자의 경우에, 기본값은 자신의 this 매개변수 값입니다. 다른 모든 함수의 경우, 기본 반환값은 {{jsxref("undefined")}}입니다.

+ +

함수 호출의 매개변수는 함수의 인수입니다. 인수는 함수에 값으로 전달됩니다. 함수가 인수값을 바꾸면, 이 변화는 전역 또는 호출한 함수에 반영되지 않습니다. 그러나, 객체 참조(reference)는 값이지만 특별합니다: 함수가 참조된 객체의 속성을 바꾸면, 그 변화는 다음 예에서와 같이 함수 밖에서도 바뀌는 것을 볼 수 있습니다:

+ +
/* 함수 'myFunc' 선언 */
+function myFunc(theObject) {
+   theObject.brand = "Toyota";
+ }
+
+ /*
+  * 변수 'mycar' 선언;
+  * 새 객체를 만들고 초기화;
+  * 'mycar'에 객체 참조를 할당
+  */
+ var mycar = {
+   brand: "Honda",
+   model: "Accord",
+   year: 1998
+ };
+
+ /* Logs 'Honda' */
+ console.log(mycar.brand);
+
+ /* 객체 참조를 함수에 전달 */
+ myFunc(mycar);
+
+ /*
+  * 함수에 의해 바뀌었기에 객체의
+  * 'brand' 속성의 값으로 'Toyota' 출력.
+  */
+ console.log(mycar.brand);
+
+ +

this 키워드는 현재 실행 중인 함수를 참조하지 않습니다, 그래서 심지어 함수 몸통 내에서도 이름으로 Function 객체를 참조해야 합니다.

+ +

함수 정의하기

+ +

함수를 정의하는 여러 방법이 있습니다:

+ +

함수 선언 (function 문)

+ +

함수 선언을 위한 특별한 구문이 있습니다 (자세한 사항은 function 문 참조):

+ +
function name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
함수 이름.
+
+ +
+
param
+
함수에 전달되는 인수의 이름. 함수는 255개까지 인수를 가질 수 있습니다.
+
+ +
+
statements
+
함수의 몸통을 구성하는 문.
+
+ +

함수 표현식 (function 식)

+ +

함수 식(expression)은 함수 선언과 비슷하고 구문이 같습니다 (자세한 사항은 function 식 참조):

+ +

함수 표현식(expression)은 함수 선언과 비슷하고 구문이 같습니다 (자세한 내용은 function expression 참조). 함수 표현식은 더 큰 표현식의 일부일 수 있습니다. "이름이 붙은(named)"함수 표현식 (예 : 호출 스택에서 표현식 이름 사용하는경우) 또는 "익명"함수 표현식을 정의 할 수 있습니다. 함수 표현식은 선언이 되지 않은 상태에서 사용할 수 없기 때문에 함수를 사용하기 전에 코드에 함수코드가 존제해야 사용 할 수 있습니다.

+ +
function [name]([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
함수 이름. 함수가 익명(anonymous) 함수로 알려진 경우, 생략될 수 있음.
+
+ +
+
param
+
함수에 전달되는 인수의 이름. 함수는 255개까지 인수를 가질 수 있습니다.
+
statements
+
함수의 몸통을 구성하는 문.
+
+ +

다음은 익명 함수 표현식의 예입니다 (이름 이 사용되지 않음):

+ +
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 benefits of creating a named function expression is that in case we encountered 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 examples do not start with the function keyword. Statements involving functions which do not start with function are function expressions.

+ +

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

+ +
(function() {
+    statements
+})();
+ +

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

+ +

생성기 함수 선언 (function* 문)

+ +

생성기 함수 선언을 위한 특별한 구문이 있습니다 (자세한 사항은 {{jsxref('Statements/function*', 'function* statement')}} 참조):

+ +
function* name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
함수 이름.
+
+ +
+
param
+
함수에 전달되는 인수의 이름.
+
+ +
+
statements
+
함수의 몸통을 구성하는 문.
+
+ +

생성기 함수 식 (function* 식)

+ +

생성기 함수 식은 생성기 함수 선언과 비슷하고 구문이 같습니다 (자세한 사항은 {{jsxref('Operators/function*', 'function* expression')}} 참조):

+ +
function* [name]([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
함수 이름. 함수가 익명 함수인 경우 생략될 수 있음.
+
+ +
+
param
+
함수에 전달되는 인수의 이름.
+
statements
+
함수의 몸통을 구성하는 문.
+
+ +

화살표 함수 표현식 (=>)

+ +

화살표 함수 식은 구문이 더 짧고 어휘상(lexically) this 값을 바인딩합니다 (자세한 사항은 화살표 함수 참조):

+ +
([param[, param]]) => {
+   statements
+}
+
+param => expression
+
+ +
+
param
+
인수의 이름. 0개 인수는 ()로 표시돼야 합니다. 인수가 1개뿐이면, 괄호는 필요치 않습니다. (foo => 1처럼)
+
statements or expression
+
선언문이 여러개인 경우 괄호로 묶여야 합니다. 단일 식(expression)은 괄호가 필요 없습니다. 그리고 식은 암시적으로(implicit) 함수의 반환값이 됩니다.
+
+ +

Function constructor

+ +
+

참고 : Function constructor를 사용하여 함수를 만드는 것은 권장되지 않습니다. 함수 본문을 일부 JS 엔진 최적화를 방해 할 수있는 문자열로 사용해야하고 다른 문제를 유발할 수 있기 때문입니다.

+
+ +

다른 모든 객체처럼, {{jsxref("Function")}} 객체는 new 연산자를 사용하여 생성될 수 있습니다:

+ +
new Function (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
형식 매개변수로 함수에 의해 사용되는 0개 이상의 이름. 각각은 알맞은 JavaScript 식별자(identifier)여야 합니다.
+
+ +
+
functionBody
+
함수 몸통을 구성하는 JavaScript 문을 포함하는 문자열.
+
+ +

함수로 Function 생성자 호출(new 연산자 사용 없이)하는 것은 생성자로 호출하는 것과 같습니다.

+ +

GeneratorFunction 생성자

+ +
+

주의: GeneratorFunction은 전역 객체가 아니지만 생성기 함수 인스턴스로부터 얻을 수 있습니다(자세한 사항은 {{jsxref("GeneratorFunction")}} 참조).

+
+ +
+

주의: GeneratorFunction 생성자를 사용하여 함수를 만드는 것은 권장되지 않습니다. 함수 본문을 일부 JS 엔진 최적화를 방해 할 수있는 문자열로 사용해야하고 다른 문제를 유발할 수 있기 때문입니다.

+
+ +

다른 모든 객체처럼, {{jsxref("GeneratorFunction")}} 객체는 new 연산자를 사용하여 생성될 수 있습니다:

+ +
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
형식 인수명으로 함수에 의해 사용되는 0개 이상의 이름. 각각은 유효한 JavaScript 식별자 규칙을 따르는 문자열 또는 콤마로 구분된 그러한 문자열 목록이어야 합니다; 예를 들어 "x", "theValue" 또는 "a,b".
+
+ +
+
functionBody
+
함수 정의를 구성하는 JavaScript 문을 포함하는 문자열.
+
+ +

함수로서 Function 생성자 호출(new 연산자 사용 없이)은 생성자로서 호출하는 것과 같은 효과입니다.

+ +

Function 매개변수

+ +

기본 매개변수

+ +

기본(default) 함수 매개변수는 전달된 값이 없거나 undefined인 경우 기본값으로 초기화되는 형식 매개변수를 허용합니다. 자세한 사항은, 기본 매개변수 참조.

+ +

나머지 매개변수

+ +

나머지(rest) 매개변수 구문은 부정(indefinite)수인 인수를 배열로 나타내는 것을 허용합니다. 자세한 사항은, 나머지 매개변수 참조.

+ +

arguments 객체

+ +

arguments 객체를 사용하여 함수 내에서 함수의 인수를 참조할 수 있습니다. arguments 참조.

+ + + +

메서드 함수 정의하기

+ +

getter 및 setter 함수

+ +

모든 표준 내장 객체 또는 새로운 속성 추가를 지원하는 사용자 정의 객체에 getter(accessor 메서드) 및 setter(mutator 메서드)를 정의할 수 있습니다. getter 및 setter를 정의하는 구문은 객체 리터럴 구문을 사용합니다.

+ +
+
get
+
+

객체 속성을 그 속성이 검색되는 경우 호출되는 함수에 바인딩합니다.

+
+
set
+
객체 속성을 그 속성을 설정하려는 시도가 있는 경우 호출되는 함수에 바인딩합니다.
+
+ +

메서드 정의 구문

+ +

ECMAScript 2015를 시작으로, getter 및 setter와 비슷한 단축 구문으로 자신의 메서드를 정의할 수 있습니다. 더 자세한 정보는 메서드 정의 참조.

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

생성자 vs. 선언문 vs. 표현식

+ +

다음을 비교해보세요:

+ +

Function constructor로 정의된 함수를 변수multiply에 할당.

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

이름이 multiply인 함수 선언:

+ +
function multiply(x, y) {
+   return x * y;
+}
+
+ +

변수 multiply에 할당된 익명(anonymous) 함수의 function 식:

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

변수 multiply에 할당된 이름이 func_name인 함수의 function 식:

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

차이

+ +

모두 거의 같은 일을 하지만 약간 미묘한 차이가 있습니다:

+ +

함수 이름과 함수가 할당 된 변수 사이에는 차이가 있습니다. 함수 이름을 변경할 수 없으며 함수가 할당 된 변수는 다시 할당 할 수 있습니다. 함수 이름은 함수 본문(body)내에서만 사용할 수 있습니다. 함수 본문(body) 외부에서 사용하려고 하면 오류가 발생합니다. (함수 이름이 var 문을 통해 이전에 선언 된 경우에는 정의되지 않습(undefined)니다.

+ +

예를 들어:

+ +
var y = function x() {};
+alert(x); // 오류 발생
+
+ +

함수 이름은 Function의 toString 메서드를 통해 직렬화되는 경우에도 보입니다.

+ +

반면에 함수가 할당 된 변수는 함수의 범위(scope)가 포함되도록 보장 된 범위로만 제한됩니다.

+ +

예제 4에서 볼 수 있듯이 함수 이름은 함수가 할당 된 변수와 다를 수 있습니다. 그들은 서로에게 아무런 관련이 없습니다. 함수 선언은 함수 이름과 동일한 이름의 변수도 만듭니다. 따라서 함수 표현식으로 정의 된 함수와 달리 함수 선언으로 정의 된 함수는 정의 된 범위에서 함수 선언의 이름으로 액세스 할 수 있습니다.

+ +

'new Function'으로 정의된 함수는 함수 이름이 없습니다. 그러나, SpiderMonkey JavaScript 엔진에서는, 함수의 직렬화된 형태가 마치 그 이름이 "anonymous"인 것처럼 보입니다. 예를 들어, alert(new Function())은 다음을 출력합니다:

+ +
function anonymous() {
+}
+
+ +

함수가 실제로는 이름이 없기에, anonymous는 함수 내에서 액세스될 수 있는 변수가 아닙니다.

+ +

다음 코드는 오류가 날 것입니다:

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

function 식 또는 Function 생성자에 의해 정의된 함수와는 달리, function 선언으로 정의된 함수는 function 자체의 선언 전에 사용될 수 있습니다. 예를 들어:

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

함수 표현식(function expression)이나 함수 선언(function declaration)에 의해 정의 된 함수는 현재 범위를 상속합니다. 즉,이 함수는 클로저를 형성합니다. 반면에 Function 생성자가 정의한 함수는 전역 범위 (모든 함수가 상속) 이외의 다른 범위를 상속하지 않습니다.

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

function 식 및 function 선언에 의해 정의된 함수는 한 번만 구문 분석됩니다, 반면에 Function 생성자에 의해 정의된 함수는 아닙니다. 즉, Function 생성자에 전달된 함수 몸통 문자열은 생성자가 호출될 때마다 구문 분석되어야 합니다. function 식이 매번 closure를 만들더라도, 함수 몸통은 다시 구문 분석되지 않습니다, 그래서 function 식은 "new Function(...)"보다 여전히 더 빠릅니다. 따라서 Function 생성자는 보통 가능한 한 피해야 합니다.

+ +

함수 식과 함수 선언으로 정의 된 함수는 한 번만 구문 분석되지만 Function 생성자로 정의 된 함수는 구문 분석되지 않습니다. 즉, Function 생성자에 전달 된 함수 본문 문자열은 생성자가 호출 될 때마다 파싱되어야합니다. 함수식이 매번 클로저(closure)를 만들지만 함수 본문은 다시 파싱되지 않으므로 함수 식은 여전히 ​​"new Function (...)"보다 빠릅니다. 따라서 Function 생성자는 가능한 피하는 것이 좋습니다.

+ +

그러나 Function constructor의 문자열을 구문 분석하여 생성된 함수 내에 중첩된 function 식 및 function 선언은 반복해서 구문 분석되지 않음에 주의해야 합니다. 예를 들면:

+ +
var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
+foo(); // 함수 몸통 문자열의 "function() {\n\talert(bar);\n}" 부분은 다시 구문 분석되지 않습니다.
+ +

function 선언은 매우 쉽게 (그리고 종종 무심코) function 식으로 바뀝니다. function 선언은 다음 어느 쪽이든 function 식이 되는 것을 중단합니다:

+ + + +
var x = 0;               // source 요소
+if (x == 0) {            // source 요소
+   x = 10;               // source 요소가 아님
+   function boo() {}     // source 요소가 아님
+}
+function foo() {         // source 요소
+   var y = 20;           // source 요소
+   function bar() {}     // source 요소
+   while (y == 10) {     // source 요소
+      function blah() {} // source 요소가 아님
+      y++;               // source 요소가 아님
+   }
+}
+
+ +

+ +
// function 선언
+function foo() {}
+
+// function 식
+(function bar() {})
+
+// function 식
+x = function hello() {}
+
+
+if (x) {
+   // function 식
+   function world() {}
+}
+
+
+// function 선언
+function a() {
+   // function 선언
+   function b() {}
+   if (0) {
+      // function 식
+      function c() {}
+   }
+}
+
+ +

블록 레벨 함수

+ +

ES2015 (ES6)를 시작으로 엄격 모드에서, 블록 내부 함수는 이제 그 블록 범위가 됩니다. ES6 이전에, 블록 레벨 함수는 엄격 모드에서 금지됐습니다.

+ +
'use strict';
+
+function f() {
+  return 1;
+}
+
+{
+  function f() {
+    return 2;
+  }
+}
+
+f() === 1; // true
+
+// 비엄격 모드에서는 f() === 2
+
+ +

비엄격 코드에서 블록 레벨 함수

+ +

한 마디로: 안됩니다.

+ +

비엄격 코드에서, 블록 내부 function 선언은 이상하게 동작합니다. 예를 들면:

+ +
if (shouldDefineZero) {
+   function zero() {     // 위험: 호환성 위험
+      console.log("This is zero.");
+   }
+}
+
+ +

ES2015는 shouldDefineZero가 false인 경우, 그러면 zero는 결코 정의되어서는 안된다고 합니다, 그 블록이 실행된 적이 없기에. 그러나, 이는 표준의 새로운 일부입니다. 역사상, 이는 지정되지 않은 채 방치되었고 일부 브라우저는 블록이 실행됐든 아니든 zero를 정의할 겁니다.

+ +

엄격 모드에서, ES2015를 지원하는 모든 브라우저는 이를 같은 식으로 다룹니다: zeroshouldDefineZero가 true이고 if 블록 범위인 경우에만 정의됩니다.

+ +

조건부 함수를 정의하는 더 안전한 방법은 function 식을 변수에 할당하는 것입니다:

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

예제

+ +

형식 갖춘 숫자 반환하기

+ +

다음 함수는 선행 0으로 채워진 형식 갖춘(formatted) 숫자 표현을 포함하는 문자열을 반환합니다.

+ +
// 이 함수는 선행 0으로 채워진 문자열을 반환
+function padZeros(num, totalLen) {
+   var numStr = num.toString();             // 문자열로 반환값을 초기화
+   var numZeros = totalLen - numStr.length; // 0의 개수 계산
+   for (var i = 1; i <= numZeros; i++) {
+      numStr = "0" + numStr;
+   }
+   return numStr;
+}
+
+ +

다음 문은 padZeros 함수를 호출합니다.

+ +
var result;
+result = padZeros(42,4); // 반환값 "0042"
+result = padZeros(42,2); // 반환값 "42"
+result = padZeros(5,4);  // 반환값 "0005"
+
+ +

함수 존재 여부 결정하기

+ +

typeof 연산자를 사용하여 함수가 존재하는지 여부를 결정할 수 있습니다. 다음 예에서, window 객체가 함수인 noFunc이라고 하는 속성이 있는지 결정하기 위해 테스트가 수행됩니다. 있으면, 사용됩니다; 그렇지 않으면 무언가 다른 행동을 취합니다.

+ +
 if ('function' == typeof window.noFunc) {
+   // noFunc() 사용
+ } else {
+   // 뭔가 다른 것 수행
+ }
+
+ +

if 테스트에는, noFunc에 대한 참조가 사용되고—실제 함수가 호출되지 않도록 함수 이름 뒤에 괄호 "()"가 없음을 주의하세요.

+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName('ES1')}}{{Spec2('ES1')}}초기 정의. JavaScript 1.0에서 구현됨
{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}신규: 화살표 함수, 생성기 함수, 기본 매개변수, 나머지 매개변수.
{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ESDraft')}}
+ +

브라우저 호환성

+ +

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

+ +

같이 보기

+ + diff --git a/files/ko/web/javascript/reference/functions/method_definitions/index.html b/files/ko/web/javascript/reference/functions/method_definitions/index.html new file mode 100644 index 0000000000..ff1b67956a --- /dev/null +++ b/files/ko/web/javascript/reference/functions/method_definitions/index.html @@ -0,0 +1,230 @@ +--- +title: 메서드 정의 +slug: Web/JavaScript/Reference/Functions/Method_definitions +tags: + - ECMAScript 2015 + - Functions + - JavaScript + - Object + - Syntax +translation_of: Web/JavaScript/Reference/Functions/Method_definitions +--- +
{{JsSidebar("Functions")}}
+ +

ECMAScript 2015 를 시작으로, 객체 초기자(initializer)에 메서드 정의를 위한 더 짧은 구문이 도입되었습니다. 이는 메서드 명에 할당된 함수를 위한 단축입니다.

+ +

구문

+ +
var obj = {
+  property( parameters… ) {},
+  *generator( parameters… ) {},
+// 키(속성) 계산값과도 함께:
+  [property]( parameters… ) {},
+  *[generator]( parameters… ) {},
+// ES5 getter/setter 구문과 비교해 보세요:
+  get property() {},
+  set property(value) {}
+};
+
+ +

설명

+ +

단축 구문은 ECMAScript 5에 도입된 gettersetter 구문과 비슷합니다.

+ +

다음 코드가 주어지면:

+ +
var obj = {
+  foo: function() {},
+  bar: function() {}
+};
+ +

이제 이를 아래로 줄일 수 있습니다:

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

주의 : 단축 구문은 익명(anonymous) 함수 (…foo: function() {}… 에서처럼) 대신 유명(named) 함수를 사용합니다. 유명 함수는 함수 본체에서 호출될 수 있습니다 (이는 참조할 식별자가 없기에 익명 함수에게는 불가능합니다). 자세한 사항은, {{jsxref("Operators/function","function","#Examples")}} 참조.

+
+ +

단축 생성기 메서드

+ +

생성기 메서드는 단축 구문을 사용해서도 정의될 수 있습니다. 단축 구문 내 별표(*)는 생성기 속성명 앞에 와야 함을 주의하세요. 즉, * g(){}는 작동하지만 g *(){}는 아닙니다.

+ +
// 유명 속성 사용 (ES2015 이전)
+var obj2 = {
+  g: function*() {
+    var index = 0;
+    while(true)
+      yield index++;
+  }
+};
+
+// 단축 구문을 쓰는 같은 객체
+var obj2 = {
+  * g() {
+    var index = 0;
+    while(true)
+      yield index++;
+  }
+};
+
+var it = obj2.g();
+console.log(it.next().value); // 0
+console.log(it.next().value); // 1
+ +

메서드 정의는 생성 불가능합니다

+ +

모든 메서드 정의는 생성자가 아니고 인스턴스화하려고 하는 경우 {{jsxref("TypeError")}} 예외가 발생합니다.

+ +
var obj = {
+  method() {},
+};
+new obj.method; // TypeError: obj.method는 생성자가 아닙니다
+
+var obj = {
+  * g() {}
+};
+new obj.g; // TypeError: obj.g는 생성자가 아닙니다 (ES2016에서 바뀜)
+
+ +

+ +

간단한 테스트 사례

+ +
var obj = {
+  a : "foo",
+  b(){ return this.a; }
+};
+console.log(obj.b()); // "foo"
+
+ +

속성 계산명

+ +

단축 구문은 속성 계산명(computed property name)도 지원합니다.

+ +
var bar = {
+  foo0 : function (){return 0;},
+  foo1(){return 1;},
+  ["foo" + 2](){return 2;},
+};
+
+console.log(bar.foo0()); // 0
+console.log(bar.foo1()); // 1
+console.log(bar.foo2()); // 2
+ +

스펙

+ + + + + + + + + + + + + + + + + + + + + + + + +
스펙상태설명
{{SpecName('ES2015', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES2015')}}초기 정의.
{{SpecName('ES7', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES7')}}생성기 메서드 역시 [[Construct]] 트랩이 없어야 하고 new와 함께 사용되는 경우 예외 발생으로 바뀜.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Method definition shorthand{{CompatChrome("39")}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatOpera("26")}}{{CompatNo}}
Generator methods are not constructable (ES2016){{CompatUnknown}}{{CompatGeckoDesktop("43")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Method definition shorthand{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Generator methods are not constructable (ES2016){{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("43")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

SpiderMonkey 전용 주의사항

+ + + +

참조

+ + diff --git a/files/ko/web/javascript/reference/functions/rest_parameters/index.html b/files/ko/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..eee5528b38 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,223 @@ +--- +title: Rest 파라미터 +slug: Web/JavaScript/Reference/Functions/rest_parameters +tags: + - Functions + - JavaScript + - Rest + - Rest parameters +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +
{{jsSidebar("Functions")}}
+ +

Rest 파라미터 구문은 정해지지 않은 수(an indefinite number, 부정수) 인수를 배열로 나타낼 수 있게 합니다.

+ +

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

+ + + +

 

+ +

구문

+ +
function f(a, b, ...theArgs) {
+  // ...
+}
+
+ +

설명

+ +

함수의 마지막 파라미터의 앞에 ... 를 붙여 (사용자가 제공한) 모든 나머지 인수를 "표준" 자바스크립트 배열로 대체합니다. 마지막 파라미터만 "Rest 파라미터" 가 될 수 있습니다.

+ +
function myFun(a, b, ...manyMoreArgs) {
+  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]
+ +

 

+ +

Rest 파라미터 및 arguments 객체간 차이

+ +

Rest 파라미터와 arguments 객체 사이에 세 가지 주요 차이점이 있습니다:

+ + + +

arguments에서 배열까지

+ +

Rest 파라미터는 인수에 의해 유발된 상용구(boilerplate) 코드를 줄이기 위해 도입되었습니다.

+ +
// Rest 파라미터 이전에, "arguments" 는 다음을 사용해 일반적인 배열로 변환될 수 있음
+
+function f(a, b) {
+
+  var normalArray = Array.prototype.slice.call(arguments);
+  // -- 또는 --
+  var normalArray = [].slice.call(arguments);
+  // -- 또는 --
+  var normalArray = Array.from(arguments);
+
+  var first = normalArray.shift(); // OK, 첫 번째 인수를 반환
+  var first = arguments.shift(); // ERROR (arguments 가 일반적인 배열이 아님)
+
+}
+
+// 이제 rest 파라미터를 사용해 쉽게 일반적인 배열에 접근할 수 있음
+
+function f(...args) {
+  var normalArray = args;
+  var first = normalArray.shift(); // OK, 첫 번째 인수를 반환
+}
+ +

Rest 파라미터 해체

+ +

Rest 파라미터는 해체될 수 있습니다(배열로만). 이는 데이터가 구분된 변수로 해체될 수 있음을 의미합니다. 구조 분해 할당 문서를 보세요.

+ +
function f(...[a, b, c]) {
+  return a + b + c;
+}
+
+f(1)          // NaN (b 와 c 는 undefined)
+f(1, 2, 3)    // 6
+f(1, 2, 3, 4) // 6 (4번 째 파라미터는 해체되지 않음)
+ +

예제

+ +

이 예제에서, 첫 번째 인수는 "a", 두 번째 인수는 "b" 로 매핑되어, 일반적인 유명 인수와 같이 사용됩니다. 반면에 3번 째 인수 "manyMoreArgs" 는 사용자가 포함시킨 인수를 포함하는 배열이 됩니다.

+ +
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]
+ +

아래를 보면, 하나의 값만 있더라도 마지막 인수는 여전히 배열을 갖습니다.

+ +
// 위 예제와 동일한 함수 정의를 사용
+
+myFun("one", "two", "three");
+
+// a, one
+// b, two
+// manyMoreArgs, [three]
+ +

아래를 보면, 3번 째 인수가 제공되지 않더라도, "manyMoreArgs" 는 여전히 배열입니다(비어있긴하지만).

+ +
// 위 예제와 동일한 함수 정의를 사용
+
+myFun("one", "two");
+
+// a, one
+// b, two
+// manyMoreArgs, []
+ +

theArgs 가 배열이므로, length 프로퍼티를 사용해 엘리먼트의 수를 얻을 수 있습니다.

+ +
function fun1(...theArgs) {
+  console.log(theArgs.length);
+}
+
+fun1();  // 0
+fun1(5); // 1
+fun1(5, 6, 7); // 3
+ +

다음 예제에서, rest 파라미터는 첫 번째 인수 다음의 모든 인수를 배열로 모으는데 사용됩니다. 각각은 첫 번째 파라미터와 곱해져 배열로 반환됩니다.

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(function(element) {
+    return multiplier * element;
+  });
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Array 메소드는 rest 파라미터에서 사용될 수 있지만, arguments 객체에서는 그렇지 않습니다.

+ +
function sortRestArgs(...theArgs) {
+  var sortedArgs = theArgs.sort();
+  return sortedArgs;
+}
+
+console.log(sortRestArgs(5, 3, 7, 1)); // 1, 3, 5, 7
+
+function sortArguments() {
+  var sortedArgs = arguments.sort();
+  return sortedArgs; // this will never happen
+}
+
+
+console.log(sortArguments(5, 3, 7, 1)); // TypeError (arguments.sort is not a function)
+ +

arguments 객체에서 Array 메소드를 사용하려면, 이를 먼저 실제 배열로 변환해야합니다.

+ +
function sortArguments() {
+  var args = Array.from(arguments);
+  var sortedArgs = args.sort();
+  return sortedArgs;
+}
+console.log(sortArguments(5, 3, 7, 1)); // 1, 3, 5, 7
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName('ES6', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성

+ +

 

+ + + +

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

+ +

함께 보기

+ + diff --git a/files/ko/web/javascript/reference/functions/set/index.html b/files/ko/web/javascript/reference/functions/set/index.html new file mode 100644 index 0000000000..248a218c37 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/set/index.html @@ -0,0 +1,208 @@ +--- +title: setter +slug: Web/JavaScript/Reference/Functions/set +translation_of: Web/JavaScript/Reference/Functions/set +--- +
{{jsSidebar("Functions")}}
+ +

set syntax는 어떤 객체의 속성에 이 속성을 설정하려고 할 때 호출되는 함수를 바인드한다.

+ +

구문

+ +
{set prop(val) { . . . }}
+{set [expression](val) { . . . }}
+ +

매개변수

+ +
+
prop
+
주어진 함수를 바인드할 속성의 이름
+
+ +
+
val
+
prop에 설정될 값을 가지고 있는 변수의 별명.
+
expression
+
ECMAScript 6부터는, 주어진 함수에 바인드 되는 속성 이름은 계산(computed)을 통해 얻을 수 있고 이것을 위한 expressions을 사용할 수 있다.
+
+ +

설명

+ +

 자바스크립트에서, setter는 특정한 속성에 값이 변경되어 질 때마다 함수를 실행하는데 사용될 수 있다. Setter는 유사(pseudo)-property 타입을 생성하는 getter와 함께 가장 자주 사용된다. 실제 값을 가지는 property와 이  property의 setter 를  동시에 갖는 것은 불가능하다.

+ +

set 문법을 사용할 때 다음을 주의한다:

+ +
+ +
+ +

setter는   delete operator를 사용하여 제거할 수 있다.

+ +

+ +

새로운 객체의 setter를 객체의 initializer에서 정의하기 

+ +

다음은 객체 o의 유사 프로러티(pseudo-property )인 current를 정의한다. 이것은 값이 설정될 때, 이 값으로 로그를 갱신 한다.

+ +
var o = {
+  set current (str) {
+    this.log[this.log.length] = str;
+  },
+  log: []
+}
+
+ +

다음 사항에 주의한다. current는 정의 되지 않았고 이것에 접근하는 모든 시도는 undefined 값을 얻게될 것이다.

+ +

delete operator로 setter를 제거하기

+ +

만약 setter를 제거하기 원한다면, 그냥 그것을 delete 하면 된다:

+ +
delete o.current;
+
+ +

defineProperty를 사용하여 이미 존재하는 객체에 setter를 정의하기

+ +

setter를 이미 존재하는 object에 나중에 언제라도 추가하기 위해서, {{jsxref("Object.defineProperty()")}}를 사용한다.

+ +
var o = { a:0 };
+
+Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
+
+o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
+console.log(o.a) // 5
+ +

연산된(computed) property name 사용하기

+ +
+

Note: 계산된(Computed) properties는 실험적인 기술이고,  ECMAScript 6 proposal의 부분이다. 아직 많은 브라우저가 지원하지 않는다. 이것 때문에 지원하지 않는 환경에서는  문법 오류가 발생할 것이다.

+
+ +
var expr = "foo";
+
+var obj = {
+  baz: "bar",
+  set [expr](v) { this.baz = v; }
+};
+
+console.log(obj.baz); // "bar"
+obj.foo = "baz";      // run the setter
+console.log(obj.baz); // "baz"
+
+ +

스펙

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Initial definition.
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Added computed property names.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
+ +

브라우저 호환성{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(1)}}{{ CompatGeckoDesktop("1.8.1") }}{{ CompatIE(9) }}9.53
Computed property names{{CompatNo}}{{ CompatGeckoDesktop("34") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{ CompatGeckoMobile("1.8.1") }}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Computed property names{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("34.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

SpiderMonkey-specific notes

+ + + +

See also

+ + diff --git "a/files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" "b/files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" new file mode 100644 index 0000000000..02dc0d55e4 --- /dev/null +++ "b/files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" @@ -0,0 +1,465 @@ +--- +title: 화살표 함수 +slug: Web/JavaScript/Reference/Functions/애로우_펑션 +tags: + - ECMAScript6 + - Functions + - Intermediate + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}}
+ +

화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메소드 함수가 아닌 곳에 가장 적합합니다. 그래서 생성자로서 사용할 수 없습니다.

+ +

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

+ +

구문

+ +

기본 구문

+ +
(param1, param2, …, paramN) => { statements }
+(param1, param2, …, paramN) => expression
+// 다음과 동일함:  => { return expression; }
+
+// 매개변수가 하나뿐인 경우 괄호는 선택사항:
+(singleParam) => { statements }
+singleParam => { statements }
+
+// 매개변수가 없는 함수는 괄호가 필요:
+() => { statements }
+ +

고급 구문

+ +
// 객체 리터럴 표현을 반환하기 위해서는 함수 본문(body)을 괄호 속에 넣음:
+params => ({foo: bar})
+
+// 나머지 매개변수기본 매개변수를 지원함
+(param1, param2, ...rest) => { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
+
+// 매개변수 목록 내 구조분해할당도 지원됨
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f();  // 6
+
+ +

상세한 구문 예는 여기에서 볼 수 있습니다.

+ +

설명

+ +

Hacks 블로그 "ES6 In Depth: Arrow functions" 포스트 참조.

+ +

화살표 함수 도입에 영향을 준 두 요소: 보다 짧아진 함수 및  바인딩하지 않은 this.

+ +

짧은 함수

+ +

일부 함수 패턴에서는, 짧은 함수가 환영받습니다. 비교해 보세요:

+ +
var elements = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryllium'
+];
+
+// 이 문장은 배열을 반환함: [8, 6, 7, 9]
+elements.map(function(element) {
+  return element.length;
+});
+
+// 위의 일반적인 함수 표현은 아래 화살표 함수로 쓸 수 있다.
+elements.map((element) => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// 파라미터가 하나만 있을 때는 주변 괄호를 생략할 수 있다.
+elements.map(element => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
+// 중괄호({})를 생략할 수 있다.
+elements.map(element => element.length); // [8, 6, 7, 9]
+
+// 이 경우 length 속성만 필요하므로 destructuring 매개변수를 사용할 수 있다.
+// 'length'는 우리가 얻고자 하는 속성에 해당하는 반면,
+// lengthFooBArX'는 변경 가능한 변수의 이름일 뿐이므로
+// 원하는 유효한 변수명으로 변경할 수 있다.
+elements.map(({ length: lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
+
+// destructuring 파라미터 할당도 아래와 같이 작성할 수 있습니다.
+// 이 예에서 정의한 객체내의 'length'에 값을 지정하지 않은 점에 주목하세요. 대신, "length" 변수의
+// 리터럴 이름은 우리가 해당 객체에서 꺼내오고 싶은 속성이름 자체로 사용됩니다.
+elements.map(({ length }) => length); // [8, 6, 7, 9] 
+ +

바인딩 되지 않은 this

+ +

화살표 함수가 나오기 전까지는, 모든 새로운 함수는, 어떻게 그 함수가 호출되는지에 따라  자신의 this 값을 정의했습니다:

+ + + +

이는 객체 지향 스타일로 프로그래밍할 때 별로 좋지않습니다.

+ +
function Person() {
+  // Person() 생성자는 `this`를 자신의 인스턴스로 정의.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // 비엄격 모드에서, growUp() 함수는 `this`를
+    // 전역 객체로 정의하고, 이는 Person() 생성자에
+    // 정의된 `this`와 다름.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

ECMAScript 3/5 에서는, 이 문제를 this 값을 폐쇄될 수 있는 (비전역) 변수에 할당하여 해결했습니다.

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // 콜백은  `that` 변수를 참조하고 이것은 값이 기대한 객체이다.
+    that.age++;
+  }, 1000);
+}
+ +

이렇게 하는 대신에, 바인딩한 함수는 적절한 this 값이 growUp() 함수에 전달될 수 있도록 생성될 수 있습니다.

+ +

화살표 함수는 자신의 this가 없습니다.  대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용됩니다; 화살표 함수는 일반 변수 조회 규칙(normal variable lookup rules)을 따릅니다. 때문에 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 끝내게 됩니다.

+ +

따라서 다음 코드에서 setInterval에 전달 된 함수 내부의 thissetInterval을 포함한 function의 this와 동일한 값을 갖습니다.

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this|는 Person 객체를 참조
+  }, 1000);
+}
+
+var p = new Person();
+ +

엄격 모드와의 관계

+ +

this가 렉시컬(lexical, 정적)임을 감안하면, this에 관한 엄격 모드 규칙은 그냥 무시됩니다.

+ +
var f = () => { 'use strict'; return this; };
+f() === window; // 혹은 전역객체
+ +

엄격 모드의 나머지 규칙은 평소대로 적용합니다.

+ +

CORRECTION: START

+ +

NOTE: the previous statement seems false.

+ +

Strict mode should prevent creating global variables when assigning to an undeclared identifier in a function.

+ +

This code sample using Chrome 81 demonstrates that arrow functions allow the creation of global variables in such situations (both for a concise body and for a normal function body):

+ +
> f1 = x => { y = x; console.log(`x: ${x}, y: ${y}`); return x + 1; }
+x => { y = x; console.log(`x: ${x}, y: ${y}`); return x + 1; }
+
+> y
+VM51587:1 Uncaught ReferenceError: y is not defined
+    at <anonymous>:1:1
+(anonymous) @ VM51587:1
+
+> f1(3)
+VM51533:1 x: 3, y: 3
+4
+
+> y
+3
+
+> f2 = x => { 'use strict'; z = x; console.log(`x: ${x}, z: ${z}`); return x + 1; }
+x => { 'use strict'; z = x; console.log(`x: ${x}, z: ${z}`); return x + 1; }
+
+> z
+VM51757:1 Uncaught ReferenceError: z is not defined
+    at <anonymous>:1:1
+(anonymous) @ VM51757:1
+
+> f2(4)
+VM51712:1 Uncaught ReferenceError: z is not defined
+    at f2 (<anonymous>:1:29)
+    at <anonymous>:1:1
+f2 @ VM51712:1
+(anonymous) @ VM51800:1
+
+> f3 = x => (z1 = x + 1)
+x => (z1 = x + 1)
+
+> z1
+VM51891:1 Uncaught ReferenceError: z1 is not defined
+    at <anonymous>:1:1
+(anonymous) @ VM51891:1
+
+> f3(10)
+11
+
+> z1
+11
+
+ +

f2 illustrates that when explicitly setting the arrow function to apply strict mode, it does throw an error when attempting to assign an undeclared variable.

+ +

https://www.ecma-international.org/ecma-262/10.0/index.html#sec-strict-mode-code

+ +

https://www.ecma-international.org/ecma-262/10.0/index.html#sec-arrow-function-definitions-runtime-semantics-evaluation

+ +

CORRECTION: END

+ +

call 또는 apply를 통한 피호출

+ +

화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드는  인자만 전달 할 수 있습니다. this는 무시됩니다.

+ +
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));         // 이는 2가 콘솔에 출력될 것임
+console.log(adder.addThruCall(1)); // 이도 2가 콘솔에 출력될 것임
+ +

바인딩 되지 않은 arguments

+ +

화살표 함수는 arguments 객체를 바인드 하지 않습니다.  때문에, arguments는  그저 둘러싸는 범위(scope) 내 이름에 대한 참조입니다.

+ +
var arguments = [1, 2, 3];
+var arr = () => arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+  var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
+  return f();
+}
+
+foo(1); // 2
+ +

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수가 좋은 대안입니다:

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

메소드로 사용되는 화살표 함수

+ +

이야기 했듯이, 화살표 함수 표현은 메소드 함수가 아닌 형태로 사용 할 수 있습니다. 메소드로 사용하려고 한면 무슨일이 발생하는지 봅시다.

+ +
'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 {...}
+
+ +

화살표 함수는 자신의 this를 가지고("bind" 바인드)있지 않습니다.{{jsxref("Object.defineProperty()")}}

+ +
'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'
+  }
+});
+ +

new 연산자 사용

+ +

화살표 함수는 생성자로서 사용될 수 없으며 new와 함께 사용하면 오류가 발생합니다.

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

prototype 속성 사용

+ +

화살표 함수는 prototype 속성이 없습니다.

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

yield 키워드 사용

+ +

yield 키워드는 화살표 함수의 본문(그 안에 더 중첩된 함수 내에서 허용한 경우를 제외하고)에 사용될 수 없습니다. 그 결과, 화살표 함수는 생성기(generator)로서 사용될 수 없습니다.

+ +

함수 본문

+ +

화살표 함수는 "concise 바디"든 보통 "block 바디"든 하나를 가질 수 있습니다.

+ +
+

concise바디는 중괄호'{}'로 묶이지않은 한줄짜리 바디이고 block바디는 중괄호로 묶인 바디입니다. 보통 여러줄 쓸때 block바디를 사용합니다.

+
+ +

block바디는 자동으로 값을 반환하지 않습니다. return을 사용해서 값을 반환해야 합니다.

+ +
var func = x => x * x;                  // concise 바디, 생략된 "return" 여기서는 x * x
+var func = (x, y) => { return x + y; }; // block 바디, "return"이 필요
+
+ +

객체 리터럴 반환

+ +

간결한 구문 params => {object:literal}을 사용한 객체 리터럴 반환은 예상대로 작동하지 않음을 명심하세요:

+ +
var func = () => {  foo: 1  };
+// func() 호출은 undefined를 반환!
+
+var func = () => {  foo: function() {}  };
+// SyntaxError: function 문은 이름이 필요함
+ +

이는 중괄호({}) 안 코드가 일련의 문(즉 foo는 라벨처럼 취급됩니다, 객체 리터럴 내 키가 아니라)으로 파싱(parse, 구문 분석)되기 때문입니다.

+ +

객체 리터럴를 괄호로 감싸는 것을 기억하세요:

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

줄바꿈

+ +

화살표 함수는 파라메터와 화살표 사이에 개행 문자를 포함 할 수 없습니다.

+ +
var func = (a, b, c)
+           => 1;
+// SyntaxError: expected expression, got '=>'
+ +

하지만, 보기 좋은 코드를 유지하고 싶다면, 아래에 보는 것처럼 괄호나 개행을 둠으로써 이를 수정할 수 있습니다.

+ +
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;
+
+// SyntaxError가 발생하지 않습니다.
+ +

파싱순서

+ +

화살표 함수 내의 화살표는 연산자가 아닙니다. 그러나 화살표 함수는 평범한 함수와 비교했을 때 operator precedence와 다르게 반응하는 특별한 파싱룰을 가지고 있습니다.

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

다른 예

+ +

기본 사용법

+ +
//  empty 화살표 함수는 undefined를 반환 
+let empty = () => {};
+
+(() => 'foobar')();
+// "foobar" 반환
+// (this is an Immediately Invoked Function Expression
+
+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]
+
+// 더 간결한 promise 체인
+promise.then(a => {
+  // ...
+}).then(b => {
+  // ...
+});
+
+// 매개변수가 없는 경우에도 더 읽기 쉬움
+setTimeout( () => {
+  console.log('I happen sooner');
+  setTimeout( () => {
+    // deeper code
+    console.log('I happen later');
+  }, 1);
+}, 1);
+ +

스펙

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}
+ +

브라우저 호환성

+ + + +

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

+ +

참조

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