>  기사  >  웹 프론트엔드  >  JavaScript 코드 작성의 다양한 함정 및 함정 채우기 방법_javascript 기술

JavaScript 코드 작성의 다양한 함정 및 함정 채우기 방법_javascript 기술

WBOY
WBOY원래의
2016-05-16 16:45:501364검색

여기서 "피트"라는 단어는 "함정"을 의미합니다. JavaScript의 "약한 언어" 특성으로 인해 사용 중에는 매우 느슨하고 유연하지만 이러한 함정에 빠지기 쉽습니다. 숨겨져 있으므로 JS를 배우고 적용하는 과정이 순조롭게 진행될 수 있도록 눈을 크게 뜨고 있어야 합니다

1. 전역변수

자바스크립트는 함수를 통해 범위를 관리합니다. 함수 내부에 선언된 변수는 함수 내부에서만 사용할 수 있고 함수 외부에서는 사용할 수 없습니다. 반면, 전역 변수는 함수 외부에서 선언되거나 선언되지 않고 단순히 사용되는 변수입니다.

"선언 없이 단순 사용"이란 var 키워드를 사용하지 않고 변수를 선언하는 것을 의미합니다. 우리는 이미 이것을 잘 알고 있습니다. 암시적으로 전역 변수를 생성하지 않는 방법은 변수를 선언할 때 var 키워드를 사용하는 것입니다.

그런데 var를 사용해도 괜찮다고 생각하시나요? 이 피트를 살펴보겠습니다.

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

function foo() {
var a = b = 0;
// 본문...
}

두 개의 지역 변수를 예상했을 수도 있지만 b는 실제 전역 변수입니다. 왜죠? 할당 작업은 오른쪽에서 왼쪽으로 진행되므로 다음과 같습니다.

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

function foo() {
var a = (b = 0);
// 본문...
}

그래서 b는 전역 변수입니다.

구멍 채우기: 변수 선언은 하나씩 하는 것이 가장 좋으며, 도매는 하지 마세요~_~;

2. 변수 선언

먼저 함정을 살펴보겠습니다:

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

myName = "global";

function foo() {
Alert(myName);
var myName = "local" ";
Alert(myName);
}

foo();

얼핏 보면 두 경고의 결과가 "전역" 및 "로컬"일 것으로 예상됩니다. "이지만 실제 결과는 "정의되지 않음" 및 "로컬"입니다. 왜 그럴까요? 변수가 동일한 범위(동일한 함수)에 있기 때문에 선언이 범위의 맨 위로 올라가서 먼저 구문 분석됩니다.

위 코드 조각의 실행 동작은 다음과 같습니다.

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

function foo() {
var myName;
경고(myName); // "정의되지 않음"
myName = "local";
경고(myName); // "local"
}

다른 피트를 사용하여 사전 구문 분석을 실제로 이해했는지 테스트하세요.
코드 복사 코드는 다음과 같습니다.

if (!("a" in window)) {
var a = 1;
}

alert (a);

변수 선언은 코드 상단으로 진행되며 아직 값이 할당되지 않았습니다. 다음으로 if 문을 입력합니다. 윈도우의 판단 조건 "a"가 성립되었으므로(a가 전역 변수로 선언됨) 판단 문 평가 결과가 false이므로 if 문이 직접 점프됩니다. a의 값은 정의되지 않았습니다.
코드 복사 코드는 다음과 같습니다.

var a; 🎜>console .log("a" in window); // true

if (!("a" in window)) {
var a = 1; // 실행하지 않음
}

alert(a); // "정의되지 않음"
변수 선언을 채우십시오. 변수 선언이 불가능한 변수의 경우 수동으로 배치하는 것이 가장 좋습니다. 현재 할당된 값은 먼저 선언한 후 값을 할당하는 방식을 채택할 수 있습니다.

3. 함수 선언

함수 선언도 범위의 최상위로 진행되어 표현식과 문보다 먼저 구문 분석되고 평가됩니다.


코드 복사 코드는 다음과 같습니다:
alert(typeof foo); // "function"

function foo() {
// 본문...
}
비교 가능:

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

alert(typeof foo); // "정의되지 않음"

var foo = function () {
// 본문...
};

이 진리를 깨달은 후에도 여전히 다음과 같은 함정에 빠지겠습니까?

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

function test() {
경고 ("1");
}

test();

function test() {
Alert("2");
}

테스트( );

위의 코드 조각을 실행하면 두 개의 팝업 창이 각각 "1"과 "2"가 아닌 이유는 무엇입니까? 간단합니다. test() 이전에 test 선언이 구문 분석되므로 후자가 전자를 재정의하므로 두 실행의 결과는 "2"입니다.

구멍 채우기: 대부분의 경우, 특히 일부 명령문 블록에서는 함수 선언 대신 함수 표현식을 사용합니다.

4. 함수 표현식

먼저 명명된 함수 표현식을 살펴보겠습니다. 물론 이름이 있어야 합니다. 예:

코드 복사 코드는 다음과 같습니다.
var bar = function foo() {
// body...
};

함수 이름은 해당 함수 내부에서만 표시된다는 점에 유의하세요. 다음과 같은 함정이 있습니다.
코드 복사 코드는 다음과 같습니다.

var bar = function foo() {
foo(); // 정상 작동
};

foo() // 오류: ReferenceError

구멍 채우기: 명명된 함수 표현식을 가능한 한 적게 사용하고(일부 재귀 및 디버깅 목적 제외) 외부에서 함수 이름을 사용하지 마십시오.

5. 함수 자체 실행

함수 표현식의 경우 뒤에 ()를 추가하면 자체 실행이 가능하며, 괄호 안에 매개변수를 전달할 수 있지만 함수 선언은 불가능합니다. . 함정:

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

// (1) 이것은 함수 호출이 아닌 그룹화 연산 기호일 뿐입니다!
// 따라서 여기 함수는 실행되지 않았으며 여전히 명령문입니다
function foo(x) {
Alert(x);
}(1);

다음 코드 조각은 각각 실행 중에 팝업 창에 "1"이 표시됩니다. (1) 앞의 모든 내용은 함수 표현식이므로 여기서 ()는 그룹화 연산자가 아니라 호출 실행을 나타내는 연산자입니다.

코드 복사 코드는 다음과 같습니다.
// 표준 익명 함수 표현식
var bar = function foo(x) {
Alert(x);
}(1);

// 이전 ()는 함수 선언을 표현식으로 변환합니다
(function foo(x) {
Alert(x);
})(1);

// 전체 ()는 표현식
(function foo(x) {
Alert(x)입니다. ;
}(1));

// 새로운 표현식
새로운 함수 foo(x) {
Alert(x);
}(1);

// &&, ||, !, , -, ~ 연산자(및 쉼표), 함수 표현식과 함수 선언의 구분
// 따라서 파서가 그 중 하나가 이미 표현식이고 나머지는 모두 기본값이라는 것을 알게 되면 to 표현식
true && function foo(x) {
Alert(x);
}(1);

채우기 구덩이: 이 구덩이 핵심은 다양한 함수 표현

6. 루프의 클로저

다음은 일반적인 함정을 보여줍니다.

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




   
문서


   

아래 링크를 클릭하면 해당 시퀀스의 번호를 표시합니다


    < ;ul>
       
  • 링크 #0

  •        
  • 링크 #1

  •        
  • 링크 #2

  •        
  • 링크 #3

  •        
  • 링크 #4

  •    


    复主代码 代码如下:

    varlinks=document.getElementsByTagName("ul")[ 0].getElementsByTagName("a");

    for (var i = 0, l =links.length; i < l; i ) {
       links[i].onclick = 함수(e ) {
            e.preventDefault();
            Alert("링크 #을 클릭하세요." i);
        }       
    }
    解释一下无: 循环内的匿名函数表达式, 保持了对外毹变weight에 대한 当 Alert 被调用时, 俤时循环已结束,i被修改为 “5” 。

    填坑:为了得到想要的结果,需要在每次循环中创建变weight i 的拷贝。以下演示正确的做法:

    复主代码 代码如下:

       
        Document


       

    아래 링크를 클릭하면 문서 개수가 표시됩니다. 해당 시퀀스


       



    复主代码 代码如下:
    varlinks=document.getElementsByTagName(“ul”)[ 0].getElementsByTagName(“a”);
    for (var i = 0, l = link.length; i < l; i ) {
       links[i].onclick = (함수 (색인) {
            반환 함수(e) {
                e.preventDefault();
                Alert("링크 #을 클릭하세요" index);
            }
        })(i);
    }

    보시다시피 (function () { ... })()의 형태는 위에서 언급한 함수의 자체 실행입니다. i는 Alert가 다시 실행될 때 인덱스에 전달됩니다. 인덱스에 대한 참조를 갖게 되며 이 값은 현재 주기적으로 변경되지 않습니다. 물론 원리를 이해한 후에는 다음과 같이 쓸 수도 있습니다.

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

    for (var i = 0, l = link.length ; i < l; i ) {
    (함수 (색인) {
    link[i].onclick = 함수 (e) {
    e.preventDefault();
    경고( "링크 #을 클릭하세요" index);
    }
    })(i);
    }

    그것도 작동합니다.

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