다음은 함수를 생성하는 표준 양식에 대한 요약입니다. (원래 다른 질문을 위해 작성되었지만 정식 질문으로 이동 한 후 수정되었습니다.)
자귀:
빠른 목록 :
함수 선언
"익명" function
표현 (이 용어에도 불구하고 때때로 이름을 가진 함수를 생성 함)
명명 된 function
표현
액세서 기능 이니셜 라이저 (ES5 +)
화살표 함수 표현식 (ES2015 +) (익명 함수 표현식과 같이 명시적인 이름은 포함하지 않지만 이름을 가진 함수는 작성할 수 있음)
객체 이니셜 라이저에서 메소드 선언 (ES2015 +)
class
(ES2015 +)의 생성자와 메소드 선언
함수 선언
첫 번째 형식은 다음과 같은 함수 선언입니다 .
function x() {
console.log('x');
}
함수 선언은 선언입니다 . 진술이나 표현이 아닙니다. 따라서, 당신은 그것을 따르지 않습니다 ;
(그러나 그렇게하는 것은 무해합니다).
함수 선언은 단계별 코드가 실행 되기 전에 실행이 표시되는 컨텍스트에 들어갈 때 처리됩니다 . 그것이 생성하는 함수는 적절한 이름 ( x
위의 예에서 )으로 주어지며 , 그 이름은 선언이 나타나는 범위에 놓입니다.
동일한 컨텍스트에서 단계별 코드 전에 처리되기 때문에 다음과 같은 작업을 수행 할 수 있습니다.
x(); // Works even though it's above the declaration
function x() {
console.log('x');
}
ES2015까지 사양은 같은 제어 구조 안에 함수 선언을 넣을 경우 자바 스크립트 엔진이 무엇을해야 적용되지 않았다 try
, if
, switch
, while
같은, 등 :
if (someCondition) {
function foo() { // <===== HERE THERE
} // <===== BE DRAGONS
}
또한 단계별 코드가 실행 되기 전에 처리되므로 제어 구조에있을 때 수행 할 작업을 아는 것이 까다 롭습니다.
이 작업은 ES2015까지 지정 되지 않았지만 블록에서 함수 선언을 지원 하는 확장이 가능 했습니다. 불행하게도 (그리고 필연적으로) 다른 엔진은 다른 일을했습니다.
ES2015 기준으로 사양에는 수행 할 작업이 나와 있습니다. 실제로 세 가지 별도의 작업을 수행합니다.
- 웹 브라우저가 아닌 느슨한 모드 인 경우 JavaScript 엔진은 한 가지 작업을 수행해야합니다.
- 웹 브라우저에서 느슨한 모드 인 경우 JavaScript 엔진은 다른 작업을 수행해야합니다
- 의 경우 엄격한 모드 (브라우저 또는하지 않음), 자바 스크립트 엔진은 또 다른 일을하도록되어
느슨한 모드에 대한 규칙은 까다 롭지 만 엄격 모드에서는 블록의 함수 선언이 쉽습니다. 블록에 대해 로컬 이며 (ES2015에서 새로운 블록 범위 를 가지며) 맨 위로 올라갑니다. 블록의. 그래서:
"use strict";
if (someCondition) {
foo(); // Works just fine
function foo() {
}
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
// because it's not in the same block)
"익명" function
표현
두 번째 일반적인 형식을 익명 함수 표현식 이라고합니다 .
var y = function () {
console.log('y');
};
모든 표현식과 마찬가지로 단계별 코드 실행에서 도달하면 평가됩니다.
ES5에서이 함수는 이름이 없습니다 (익명). ES2015에서는 가능한 경우 컨텍스트에서 유추하여 함수에 이름이 지정됩니다. 위의 예에서 이름은입니다 y
. 함수가 속성 이니셜 라이저 값일 때 비슷한 작업이 수행됩니다. (이 상황과 규칙에 대한 자세한 내용 은 사양SetFunctionName
에서 검색 하십시오. 모든 곳에서 나타납니다 .)
명명 된 function
표현
세 번째 형식은 명명 된 함수 표현식 ( "NFE")입니다.
var z = function w() {
console.log('zw')
};
이 함수는 적절한 이름을 가지고 있습니다 ( w
이 경우). 모든 표현식과 마찬가지로 단계별 코드 실행에서 도달하면 평가됩니다. 함수 이름은 표현식이 나타나는 범위에 추가 되지 않습니다 . 이름 은 함수 자체의 범위 내에 있습니다.
var z = function w() {
console.log(typeof w); // "function"
};
console.log(typeof w); // "undefined"
NFE는 종종 JavaScript 구현을위한 버그의 원인이되었습니다. 예를 들어 IE8 및 이전 버전에서는 NFE를 완전히 잘못 처리 하여 두 가지 다른 시간에 두 가지 다른 기능을 만듭니다. 초기 버전의 Safari에도 문제가있었습니다. 좋은 소식은 최신 버전의 브라우저 (IE9 이상, 현재 Safari)에는 더 이상 이러한 문제가 없다는 것입니다. (그러나이 글을 쓰는 시점에서 슬프게도 IE8은 널리 사용되므로 웹 코드를 사용하여 NFE를 사용하는 것은 여전히 문제가됩니다.)
액세서 기능 이니셜 라이저 (ES5 +)
때로는 기능이 크게 눈에 띄지 않게 몰래 들어갈 수 있습니다. 접근 자 함수 의 경우입니다 . 예를 들면 다음과 같습니다.
var obj = {
value: 0,
get f() {
return this.value;
},
set f(v) {
this.value = v;
}
};
console.log(obj.f); // 0
console.log(typeof obj.f); // "number"
함수를 사용할 때 사용하지 않았습니다 ()
! 속성에 대한 접근 자 기능 이기 때문 입니다. 우리는 일반적인 방법으로 속성을 가져오고 설정하지만, 뒤에서 함수가 호출됩니다.
당신은 또한에 접근 기능을 만들 수 있습니다 Object.defineProperty
, Object.defineProperties
그리고에 덜 알려진 두 번째 인수를 Object.create
.
화살표 함수 표현 (ES2015 +)
ES2015는 화살표 기능을 제공 합니다. 예를 들면 다음과 같습니다.
var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6
그 참조 n => n * 2
의 일이 숨어 map()
전화를? 그것은 기능입니다.
화살표 기능에 대한 몇 가지 사항 :
그들에게는 자신의 것이 없습니다 this
. 대신, 그들은 가까운 이상this
가 정의하고있는 문맥. (또한 닫고 arguments
관련이있는 경우 super
.) 이는 this
내부 this
가 작성 위치 와 동일 하며 변경할 수 없음을 의미합니다.
위에서 알 수 있듯이 키워드를 사용하지 않습니다 function
. 대신을 사용 =>
합니다.
n => n * 2
위 의 예는 그중 하나입니다. 함수를 전달할 인수가 여러 개인 경우 parens를 사용합니다.
var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6
(즉 기억 Array#map
첫 번째 인수로 진입하고, 상기 제로서 인덱스를 통과한다.)
두 경우 모두 함수의 본문은 표현식 일뿐입니다. 함수의 반환 값은 자동으로 해당 표현식의 결과가됩니다 (명시 적을 사용하지 않음 return
).
단일 표현식 이상을 수행하는 경우 평소 {}
와 같이 명시 적 return
(값을 반환해야하는 경우)을 사용하십시오.
var a = [
{first: "Joe", last: "Bloggs"},
{first: "Albert", last: "Bloggs"},
{first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
var rv = a.last.localeCompare(b.last);
if (rv === 0) {
rv = a.first.localeCompare(b.first);
}
return rv;
});
console.log(JSON.stringify(a));
없는 버전 { ... }
은 표현식 본문 또는 간결한 본문이 있는 화살표 함수라고합니다 . (또한하십시오 간결한 . 화살표 기능)와 하나의 { ... }
몸체를 형성은 A의 화살표 함수 기능 체 . (또한 : 자세한 화살표 기능)
객체 이니셜 라이저에서 메소드 선언 (ES2015 +)
ES2015는 메소드 정의 라는 함수를 참조하는 속성을 선언하는 짧은 형식을 허용합니다 . 다음과 같이 보입니다 :
var o = {
foo() {
}
};
ES5 및 그 이전 버전과 거의 동등한 내용은 다음과 같습니다.
var o = {
foo: function foo() {
}
};
(자세한 것 이외의) 차이점은 메소드가을 사용할 수 super
있지만 함수는 사용할 수 없다는 것입니다. 예를 들어, valueOf
메소드 구문을 사용하여 정의 된 객체가있는 경우 ES5 버전이 대신 수행해야하는 반면 super.valueOf()
값 Object.prototype.valueOf
을 반환 하는 데 사용할 수 있습니다 (아마도 다른 작업을 수행하기 전에) Object.prototype.valueOf.call(this)
.
즉, 메소드에 정의 된 오브젝트에 대한 참조가 메소드에 있음을 의미하므로 해당 오브젝트가 임시 인 경우 (예 : Object.assign
소스 오브젝트 중 하나로 전달하는 경우 ) 메소드 구문 은 오브젝트가 유지됨을 의미 할 수 있습니다. 그렇지 않으면 메모리에 가비지 수집되었을 수 있습니다 (JavaScript 엔진이 해당 상황을 감지하지 않고 메소드를 사용하지 않는 경우 처리하지 않는 경우 super
).
class
(ES2015 +)의 생성자와 메소드 선언
ES2015는 class
선언 된 생성자와 메소드를 포함한 구문을 제공 합니다 :
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return this.firstName + " " + this.lastName;
}
}
위에는 두 개의 함수 선언이 있습니다. 하나는 생성자를 Person
위한 것이고 다른 하나 getFullName
는에 할당 된 함수 Person.prototype
입니다.