>  기사  >  웹 프론트엔드  >  JavaScript의 변수 범위 및 메모리 문제 이해

JavaScript의 변수 범위 및 메모리 문제 이해

php是最好的语言
php是最好的语言원래의
2018-08-03 10:17:571081검색

가변 범위 및 메모리 문제

1. 기본 유형의 값과 참조 유형

기본 유형은 단순 데이터 세그먼트(5가지 값 유형)인 반면, 참조 유형은 객체(객체에 대한 참조 조작)입니다.

1.1 변수 값 복사

참조 유형은 실제로 복사가 완료된 후 함수 포인터를 전달합니다. 이 개체를 변경하면 두 변수는 실제로 힙 메모리에 있는 동일한 개체를 참조합니다. 변수도 동기적으로 변경됩니다.

1.2 매개변수 전달

함수의 매개변수는 모두 값으로 전달됩니다. 사실 저는 이 진술이 다소 추상적이라고 생각합니다. 이렇게 정리하는 것이 더 좋습니다. 함수에 전달된 변수가 값 유형인 경우 함수에 전달된 원래 변수의 은 함수 내부의 영향으로 인해 변경되지 않습니다. 함수에 전달된 변수가 참조형(객체)인 경우, 함수에 전달된 원래 변수의 참조는 함수 내부의 영향으로 변경되지 않습니다. 사실 여기서는 이해하기 쉽지 않습니다. 예를 들어 설명하기 위해 예를 들어보세요.

        var obj = {
            name: 'andy'
        }

        function ChangeObj(val) {
            val.age = '25'
            val = {
                name:'zakas',
                age:40
            }
            return val;
        }
        ChangeObj(obj); // {name:'zakas',age:40}
        console.log(obj) // {name:'andy',age:25}

위의 예에서는 함수에 전달된 경우 val의 메모리 주소가 변경되었습니다. reference이면 val의 참조는 obj입니다. reference와 val의 적용이 변경되면 obj의 참조도 그에 따라 변경되므로 obj의 결과도 {name:'zakas',age:40}이어야 합니다. 값으로 전달된 경우 obj는 val에 대한 참조에 할당되지만 해당 참조는 함께 연결되지 않습니다. val 참조에 대한 변경은 obj의 참조 주소에 영향을 주지 않습니다.

함수의 형식 매개변수는 함수 범위의 지역 변수입니다. 함수 실행이 끝나면 삭제됩니다.

1.3 감지 유형

instanceof는 참조 유형을 보다 명시적으로 감지할 수 있습니다. 따라서 인스턴스 오브의 값 유형은 항상 false이며 값 유형을 감지하기 위해 해당 메소드를 사용할 필요가 없습니다. instanceof는 Array Object와 RegExp

만 구분할 수 있습니다. 실행 환경

각 실행 환경에는 변수 객체가 있습니다. 변수 객체의 개념은 매우 중요합니다. 이는 범위에 정의된 모든 변수의 대규모 모음입니다. 각 실행 환경에는 우리가 정의한 모든 변수를 저장하는 변수 개체가 있지만 이 변수 ​​개체에 액세스할 수는 없지만 파서가 데이터를 처리할 때 사용됩니다. 백그라운드에서.

    function A() {
        var tempA;
        function B() {
            var tempB;
            function C() {
                var tempC
            }
        }
    }

B()의 스코프 체인에는 3개의 객체가 포함되어 있습니다. 하나는 자체 변수 객체이고 A의 변수 객체와 전역 변수 객체입니다. A()의 범위 체인에는 A() 자체 변수 개체와 전역 변수 개체라는 2개의 개체가 포함되어 있습니다. 따라서 A는 B의 변수에 액세스할 수 없고 자신의 전역 변수에만 액세스할 수 있습니다. 그러나 B는 자신의 변수뿐만 아니라 A의 변수와 전역 범위에도 액세스할 수 있습니다.

2.1 범위 체인 확장

with

With는 현재 범위 위에 새 변수 개체를 만드는 것과 같습니다. 예:

    var obj = {
        name:'andy',
        sex:'man',
        hobby:'game'
    }
    function fn() {
        with(obj) {
            fnName = name;
            fnSex = sex;
            fnHobby = hobby;
        }
        console.log(fnName,fnSex,fnHobby) // andy,man,game
    }
    fn()

With 메소드는 심각한 성능 손실을 초래하므로 일반적으로

2.2 블록 수준 범위 없음

을 사용하는 것을 권장하지 않습니다. 이 개념, 기능 및 차이점을 알아야 합니다. 가장 일반적인 질문은

for(var i =0 ; i < 10 ; i++ ) {
    setTimeout(function(){
        console.log(i);
    },0)
}
입니다.

이 문제를 이해하는데 있어서 먼저 타이머가 비동기식이라는 것을 알아야 합니다. 0이더라도 먼저 캐시 영역에 배치한 다음 다른 프로그램이 위에서 아래로 실행을 완료한 후에 호출해야 합니다. 그래서 다른 프로그램을 위에서 아래로 실행한 후에는 블록 수준의 범위가 없으므로 i는 전역이고 10이 되므로 10 10s가 출력됩니다. 블록 수준 범위를 사용하도록 i를 변경하면 문제가 해결됩니다.

for(let i =0 ; i < 10 ; i++ ) {
    setTimeout(function(){
        console.log(i);
    },0)
}

2.3 가비지 수집

JavaScript에는 자동 가비지 수집 메커니즘이 있습니다

값을 사용하는 과정은 실제로 변수에 의해 할당된 메모리를 쓰고 읽는 것과 같습니다. JavaScript는 변수를 생성하는 동안 메모리를 할당하고 변수가 사용되지 않을 때 자동으로 해제합니다. 이 프로세스를 가비지 수집 메커니즘이라고 합니다. 그러나 이러한 자동성 때문에 많은 개발자는 그렇게 할 필요가 없다고 생각합니다. 메모리 문제에 너무 신경을 쓰는 것은 잘못된 것입니다.

Principle: 가비지 프로세서는 기본적으로 주기적으로 감지하고 사용되지 않는 변수를 찾은 다음 메모리를 해제합니다.
재활용 전략: 로컬 환경에서 함수가 호출된 후 가비지 수집기는 어떤 변수가 유용하고 어떤 변수가 쓸모 없는지 추적하여 메모리 재활용을 준비하도록 표시합니다. 일반적으로 두 가지 다른 전략이 있습니다:

  • 마크 지우기: 2012년부터 모든 브라우저는 가비지 수집을 위해 마크 지우기 방법을 사용했으며 js 가비지 수집에 대한 모든 개선 사항도 알고리즘 최적화를 위한 마크 지우기 방법을 기반으로 합니다.

  • 참조 카운팅: 심각한 순환 참조 문제가 있어 기본적으로 더 이상 사용되지 않습니다.

따라서 고성능 페이지에서는 메모리를 적게 차지하는 프로그램을 작성할 때 매우 중요한 포인트입니다. 따라서 프로그램을 작성할 때 데이터가 더 이상 필요하지 않으면 이를 dereference

로 null로 설정하는 것이 가장 좋습니다. 관련 기사:

JavaScript 변수 범위 및 메모리 문제 (2)

Li Yanhui Javascript 동영상 튜토리얼

위 내용은 JavaScript의 변수 범위 및 메모리 문제 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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