>  기사  >  웹 프론트엔드  >  JavaScript 기능에 대한 자세한 설명_기본지식

JavaScript 기능에 대한 자세한 설명_기본지식

WBOY
WBOY원래의
2016-05-16 16:31:141257검색

소개

많은 기존 언어(C/C/Java/C# 등)에서 함수는 언어 키워드를 사용하여 함수를 선언한 다음 사용해야 하는 경우에만 호출할 수 있습니다. 함수를 매개변수로 다른 함수에 전달하거나, 지역 변수에 할당하거나, 반환 값으로 사용하려면 함수 포인터, 대리자 등 특수한 메서드를 거쳐야 합니다.
JavaScript 세계에서 함수는 일급 시민입니다. 기존 함수(선언 및 호출)를 사용하는 모든 방법을 가질 뿐만 아니라 값을 할당하고 매개변수를 전달하고 간단한 값처럼 반환할 수도 있습니다. - 일류 함수. 뿐만 아니라 JavaScript의 함수는 클래스의 생성자 역할도 하며 Function 클래스의 인스턴스이기도 합니다. 이러한 다중 ID는 JavaScript 기능을 매우 중요하게 만듭니다.

1. 입문용 자바스크립트 함수

다른 언어와 마찬가지로 JavaScript 함수는 먼저 선언하고 나중에 사용하는 원칙을 따릅니다. 함수 이름에는 문자, 숫자, 밑줄 또는 $만 포함될 수 있으며 숫자로 시작할 수 없습니다. 함수를 선언하는 일반적인 방법에는 두 가지가 있습니다:

코드 복사 코드는 다음과 같습니다.

// myfunc 함수를 직접 선언합니다
함수 myfunc(/* 인수 */) {
}

//익명 함수를 지역 변수 myfunc
에 할당합니다. var myfunc = 함수(/* 인수 */) {
}

위의 두 함수 선언 방법에는 미묘한 차이가 있습니다. 첫 번째 방법은 호출 전, 호출 후 또는 실행되지 않는 위치에 선언되는지 여부에 관계없이 선언할 때 명명된 함수입니다. (예: return 문 또는 결코 true가 아닌 분기)은 전체 범위에서 액세스할 수 있습니다. 두 번째 방법은 엄밀히 말하면 함수 선언(함수 선언)이 아닌 변수에 익명 함수를 할당하는 것입니다. 이 함수는 할당 전에 어떤 코드에서도 액세스할 수 없습니다. 즉, 호출하기 전에 할당을 완료해야 합니다. 그렇지 않으면 호출 시 "TypeError: undefed is a function"이라는 오류가 발생합니다. 예:

코드 복사 코드는 다음과 같습니다.

myfunc1(); // myfunc1을 직접 선언했기 때문에 정상적으로 호출 가능

함수 myfunc1() {
}

myfunc2(); // 오류 TypeError: 정의되지 않은 것은 함수가 아닙니다

var myfunc2 = function() {
};


함수를 호출하는 기본 방법은 한 쌍의 괄호를 사용하는 전통적인 언어와 동일합니다: myfunc(). JavaScript 함수는 직접 또는 간접 재귀 호출도 지원합니다. 예를 들어 클래식 Fibonacci 함수는 다음과 같이 JavaScript로 구현될 수 있습니다.

코드 복사 코드는 다음과 같습니다.
함수 fib(n) {
If (n == 1 || n == 2) {
1을 반환합니다.
} 다른 {
fib(n - 2) fib(n - 1)을 반환합니다.
}
}

JavaScript의 함수는 가변 길이 매개변수를 처리할 수 있습니다. 인수라는 로컬 변수는 호출 시 전달되는 모든 매개변수를 포함하는 배열과 유사한 객체입니다. . 예:

코드 복사 코드는 다음과 같습니다.
함수 테스트() {
경고(인수.길이)
}

테스트(1); // 1
테스트(1, 'a'); // 2
test(true, [], {}); // 3 인수는 C 언어 printf와 유사한 기능을 구현하는 데 사용할 수 있으며 메소드 다형성을 구현하는 데에도 사용할 수 있습니다.

2. 고급 자바스크립트 기능

2.1 익명 함수와 중첩 함수

JavaScript에서는 익명 함수라고 하는 이름 없이 함수를 선언할 수 있습니다. 동시에 JavaScript에서는 중첩 함수라고 하는 함수 내부에서 함수를 선언할 수도 있습니다. 중첩 함수의 범위는 전체 상위 함수입니다.

이전 함수 선언 섹션에서 익명 함수와 중첩 함수의 사용을 살펴보았습니다. 익명 함수에는 이름이 없으므로 컨텍스트를 오염시키는 새 변수를 도입하지 않고 새 변수 범위를 가져오는 경우가 많습니다. 지구 환경 오염을 방지하기 위해 사용됩니다.

JavaScript 런타임에는 특별한 전역 환경(전역 객체)이 있는데, 이 객체는 전역 함수와 변수를 저장하며, 실제 개발에서는 전역 객체 변수에 실수로 중복이 발생하는 경우 여러 타사 라이브러리가 사용되는 경우가 많습니다. 또는 함수 선언으로 인해 코드 실행에 혼란이 발생합니다. 예를 들어, 두 개의 js 파일이 차례로 도입되고 각각은 내부 사용을 위해 자체 함수 로그를 정의하며 두 번째로 도입된 함수는 첫 번째 정의를 덮어쓰며 후속 실행에서 로그 함수를 호출하면 문제가 발생하지 않을 수 있습니다. 오류를 유발합니다. 이때 익명 함수를 사용하여 전체 js에서 로직을 래핑하면 이 오류를 피할 수 있습니다. 이 방법은 대부분의 오픈 소스 js 라이브러리에서 사용되었습니다.

코드 복사 코드는 다음과 같습니다.

(function() { // 익명 함수

함수 로그(msg) {
console.log(msg)
}

// 기타 코드

}()); // 즉시 실행

위 코드는 간단한 예시로, 로그 함수의 범위는 이 익명 함수로 제한되며, 익명 함수를 외부에 한 쌍의 괄호()로 묶어 함수 표현식을 구성합니다. 함수 뒤에 괄호 한 쌍을 붙여 함수가 즉시 실행됨을 나타내므로 원래 코드가 정상적으로 실행될 수 있습니다. 그러나 이렇게 선언된 함수, var를 통해 선언된 변수 등은 내부적이므로 익명 함수가 아닌 다른 코드에서는 접근할 수 없습니다. 일부 기능을 인터페이스로 노출해야 하는 경우 다음과 같은 여러 가지 방법이 있습니다.

코드 복사 코드는 다음과 같습니다.

var mylib = (함수(전역) {

함수 로그(msg) {
console.log(msg)
}

log1 = log; // 방법 1: var 없이 변수 선언의 기본 동작을 사용하고 log1을 전역 변수로 만듭니다(권장하지 않음)

global.log2 = log; // 방법 2: 전역 객체에 직접 log2 속성을 추가하고 로그 함수에 값을 할당합니다(권장)

return { // 방법 3: 익명 함수의 반환 값을 통해 일련의 인터페이스 함수 컬렉션 객체를 획득하고 이를 전역 변수 mylib에 할당합니다(권장)
로그: 로그
};
}(창));

2.2 고차함수

함수를 매개변수나 반환값으로 사용하는 경우를 고차함수라고 합니다. 자바스크립트의 모든 함수는 고차함수로 사용될 수 있는 것도 첫 번째 유형의 함수입니다. 아래에서는 이 두 가지 사용 방법을 각각 분석해 보겠습니다.

코드 복사 코드는 다음과 같습니다.
함수 부정(n) {
Return -n; // n의 반대값을 취함
}

함수 square(n) {
n*n 반환; // n 제곱
}

함수 프로세스(숫자, 콜백) {
var 결과 = []

for(var i = 0, length = nums.length; i result[i] = callback(nums[i]); // 처리를 위해 배열 nums의 모든 요소를 ​​콜백에 전달하고 반환 값을 결과로 저장합니다.
}

결과 반환
}

var nums = [-3, -2, -1, 0, 1, 2, 3, 4]
var n_neg = 프로세스(숫자, 음수)
// n_neg = [3, 2, 1, 0, -1, -2, -3, -4]
var n_square = 프로세스(숫자, 사각형)
// n_square = [9, 4, 1, 0, 1, 4, 9, 16];

위 코드는 함수를 다른 함수 프로세스 호출에 매개변수로 전달하는 예를 보여줍니다. 프로세스 함수 구현에서 콜백은 매개변수를 전달하고 가져오는 역할을 하는 블랙박스로 처리됩니다. 반환 값. 이전에는 콜백의 구체적인 구현이 명확하지 않았습니다. 20행과 22행이 실행될 때만 콜백은 각각 음수 또는 제곱으로 표현되며, 각 요소에 대해 각각 반대값 또는 제곱값 연산이 수행됩니다.

코드 복사 코드는 다음과 같습니다.

함수 생성기() {
변수 i = 0
반환 함수() {
반품
}; }

var gen1 = Generator(); // 자연수 생성기 가져오기
var gen2 = Generator(); // 또 다른 자연수 생성기 가져오기
var r1 = gen1(); // r1 = 0
var r2 = gen1(); // r2 = 1
var r3 = gen2(); // r3 = 0
var r4 = gen2(); // r4 = 1

위 코드는 함수를 반환값으로 사용하는 예를 보여줍니다. 생성기는 자연수 생성기 함수이고, 반환값은 자연수 생성기 함수입니다. 생성기가 호출될 때마다 익명 함수가 결과로 반환됩니다. 이 익명 함수는 실제로 호출될 때 각 자연수를 차례로 반환합니다. 생성기의 변수 i는 이 익명 함수가 호출될 때마다 1씩 증가합니다. 이는 실제로 클로저입니다. 아래에 클로저를 소개하겠습니다.




2.3 폐쇄 클로저(Closure)는 새로운 개념이 아닙니다. 클로저는 많은 함수형 언어에서 사용됩니다. JavaScript에서는 인라인 함수 내의 외부 함수 범위 내에서 변수를 사용할 때 클로저가 사용됩니다. 클로저와 클래스 사이의 관계를 설명하려면 일반적인 비유를 사용하십시오. 클래스는 함수가 있는 데이터이고 클로저는 데이터가 있는 함수입니다.
클로저에 사용되는 변수의 한 가지 특징은 부모 함수가 반환될 때 해제되지 않고 클로저 수명 주기가 끝나면 종료된다는 것입니다. 예를 들어 이전 섹션의 생성기 예제와 같이 gen1과 gen2는 gen1 또는 gen2인 한 독립 변수 i를 사용합니다(gen1의 i가 1 증가해도 gen2의 i는 영향을 받지 않으며 그 반대도 마찬가지임). JavaScript 엔진에 의해 가비지 수집되지 않으므로 해당 변수 i가 해제되지 않습니다. JavaScript 프로그래밍에서 클로저는 무의식적으로 사용됩니다. 클로저의 이러한 기능은 사용 편의성을 제공하지만 메모리 누수와 같은 문제를 쉽게 일으킬 수도 있습니다. 예:

코드 복사 코드는 다음과 같습니다.
var elem = document.getElementById('test')
elem.addEventListener('click', function() {
Alert('elem.tagName)을 클릭했습니다.
});

이 코드의 기능은 클릭 시 노드의 라벨 이름을 표시하는 것입니다. DOM 노드의 클릭 이벤트 처리 기능으로 익명 함수를 등록합니다. 함수에서 DOM 개체 요소를 참조하여 닫힌 가방. 그러면 순환 참조가 생성됩니다. 즉, DOM-> Closure->DOM-> Closure... DOM 객체는 클로저가 해제되기 전에는 해제되지 않으며 클로저는 DOM의 이벤트 처리 기능으로 사용됩니다. 객체가 존재하므로 DOM 객체가 해제되기 전에는 클로저가 해제되지 않습니다. DOM 트리에서 DOM 객체가 삭제되더라도 이 순환 참조의 존재로 인해 DOM 객체도 클로저도 해제되지 않습니다. 다음 방법을 사용하면 이러한 메모리 누수를 방지할 수 있습니다.

코드 복사 코드는 다음과 같습니다.
var elem = document.getElementById('test')
elem.addEventListener('click', function() {
Alert('this.tagName); // 더 이상 elem 변수를 직접 참조하지 않습니다.
});

위 코드에서는 elem(DOM 이벤트 처리 함수에서 this 포인터가 DOM 요소 자체를 가리킴) 대신 this를 사용하므로 JS 런타임에서는 더 이상 상위 클래스의 변수가 사용되는 것으로 간주하지 않습니다. 이 함수에서는 더 이상 클로저가 형성되지 않습니다.

클로저는 또한 유사한 메모리 누수 문제를 많이 발생시킵니다. 이러한 문제를 피하려면 코드를 작성할 때에만 클로저에 주의하십시오.


2.4 클래스 생성자
JavaScript 함수는 클래스의 생성자 역할도 하므로 함수를 선언하기만 하면 new 키워드를 사용하여 클래스의 인스턴스를 만들 수 있습니다.

코드 복사 코드는 다음과 같습니다.

함수 사람(이름) {
This.name = 이름
This.toString = function() {
'안녕하세요, 'this.name'!'을 반환합니다. }; }

var p = new Person('Ghostheaven')
Alert(p); // Hello, Ghostheaven! 위의 예에서는 Person 함수가 클래스의 생성자로 사용되었습니다. 이때 새로 생성된 인스턴스 개체에 속성과 메서드를 추가할 수 있습니다. 자세한 객체지향 JavaScript 프로그래밍에 대해서는 이 글을 참고하세요. 여기서 제가 이야기하고 싶은 것은 JavaScript 함수를 클래스 생성자로 사용할 때 반환 값 문제입니다.


함수 MyClass(이름) {
This.name = 이름
반환 이름; // 생성자의 반환 값
}

var obj1 = new MyClass('foo')
var obj2 = MyClass('foo')
var obj3 = new MyClass({})
var obj4 = MyClass({});


위 생성자는 매우 특별합니다. return 문이 있는데, obj1~obj4는 각각 어떤 객체를 가리킵니까? 실제 결과는 이렇습니다.

obj1 = MyClass 객체
obj2 = 'foo'
obj3 = {}
obj4 = {}


구체적인 이유는 이 글에서 설명하고, 이 글에서는 자세히 다루지 않겠습니다. 반환값을 갖는 생성자는 이상한 결과를 낳기 때문에 생성자에서 반환값을 갖는 return 문을 호출하지 마세요. 빈 반환은 괜찮습니다).


3. 자바스크립트 함수 괴물 수준

몬스터 레벨 기능 교육 영역에 오신 것을 환영합니다. 몬스터를 차분하고 편안하게 대하는 방법을 가르쳐드립니다. . .


3.1 함수 클래스
JavaScript 런타임에는 Function이라는 내장 클래스가 있습니다. function 키워드를 사용하여 함수를 선언하는 것은 실제로 Function 클래스 개체를 만드는 간단한 형식입니다. 그리고 바인딩하세요. 인스턴스 오브 키워드를 통해 이 명령문을 확인할 수 있습니다. Function은 클래스이므로 그 생성자는 Function(자체도 Function 클래스의 객체임)이고, new 키워드를 통해 함수 객체 생성이 가능해야 한다. 여기에 Function 클래스를 사용하여 함수를 구성하는 방법에 대한 첫 번째 괴물이 있습니다. Function의 구문은 다음과 같습니다.

새 함수([arg1[, arg2[, ... argN]],] functionBody)


그 중 arg1, arg2, ... argN은 매개변수 이름을 나타내는 문자열이고, functionBody도 함수 본문을 나타내는 문자열입니다. 이전 매개변수 이름은 Function의 생성자가 처리합니다. 마지막 매개변수 as 함수 본문에서 이전 매개변수는 매개변수로 처리됩니다.

var func1 = new Function('name', 'return "Hello, " name "!";'); func1('Ghostheaven'); // 안녕하세요, 고스트헤븐님!



위 메서드는 Function을 통해 함수를 구성합니다. 이 함수는 function 키워드로 선언된 다른 함수와 완전히 동일합니다.
이것을 보고 많은 사람들은 왜 그런 괴물이 필요한가? "존재하는 것은 무엇이든 합리적입니다." Function 클래스는 이를 사용하여 다양한 함수 논리를 동적으로 생성하거나 평가 함수의 함수를 대체하고 현재 환경이 오염되는 것을 방지할 수 있습니다*.



3.2 자체 업데이트 기능

많은 언어에서 함수가 선언되면 같은 이름의 함수를 다시 선언할 수 없습니다. 그렇지 않으면 구문 오류가 발생합니다. 그러나 JavaScript의 함수는 반복적으로 선언될 수 있을 뿐만 아니라 자체 업데이트도 가능합니다. 스스로 잡아먹는 괴물이 나타났다!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.