찾다
웹 프론트엔드JS 튜토리얼js 범위 및 클로저에 대한 자세한 설명

js 범위 및 클로저에 대한 자세한 설명

Scope

JS에는 두 가지 종류의 범위가 있습니다: 전역 범위|로컬 범위

Chestnut 1

console.log(name);      //undefined
var name = '波妞';
var like = '宗介'
console.log(name);      //波妞
function fun(){
    console.log(name);  //波妞
    console.log(eat)    //ReferenceError: eat is not defined
    (function(){
        console.log(like)   //宗介
        var eat = '肉'
    })()
}
fun();

[관련 강좌 추천: JavaScript 비디오 튜토리얼]

1. 이름 입니다. 전역적으로 정의되고 전역적으로 액세스할 수 있으므로 (2) 인쇄가 올바르게 인쇄될 수 있습니다.

2. fun 함수에서 name 속성이 정의되지 않은 경우 이를 찾기 위해 상위 범위로 이동합니다. 올바르게 인쇄할 수 있습니다.

3. 내부 환경은 스코프 체인을 통해 모든 외부 환경에 접근할 수 있지만, 외부 환경은 내부 환경의 어떤 변수나 기능에도 접근할 수 없습니다. 단방향 투명성과 유사하게 이는 범위 체인이므로 (4)는 작동하지 않지만 (5)는 작동합니다.

그러면 첫 번째 인쇄가 "ReferenceError: 이름이 정의되지 않았습니다"가 아닌 "정의되지 않음"인 이유에 대한 질문이 나옵니다. 원칙은 단순히 JS의 변수 승격

변수 승격: JS는 코드를 구문 분석할 때 모든 선언을 범위 앞쪽으로 진행한다는 것입니다.


Chestnut 2

console.log(name);      //undefined
var name = '波妞';
console.log(name);      //波妞
function fun(){
    console.log(name)   //undefined
    console.log(like)   //undefined
    var name = '大西瓜';
    var like = '宗介'
}
fun();

Quite Note on

var name;
console.log(name);      //undefined
name = '波妞';
console.log(name);      //波妞
function fun(){
    var name;
    var like;
    console.log(name)   //undefined
    console.log(like)   //undefined
    name = '大西瓜';
    like = '宗介'
    console.log(name)   //大西瓜
    console.log(like)   //宗介
}
fun();

: 는 현재 범위의 맨 앞으로 이동합니다.


Chestnut 3

printName();     //printName is not a function
var printName = function(){
    console.log('波妞')
}
printName();       //波妞

var printName;
printName();     //printName is not a function
printName = function(){
    console.log('波妞')
}
printName();       //波妞

과 동일합니다. 이렇게 하면 이해하기 쉽습니다. 함수 표현식은 변수로 선언될 때 함수일 뿐입니다.


Chestnut 4

{
    var name = '波妞';
}
console.log(name)   //波妞

(function(){
    var name = '波妞';
})()
console.log(name)   //ReferenceError: name is not defined

{
    let name = '波妞';
}
console.log(name)   //ReferenceError: name is not defined

위의 chestnut에서 볼 수 있듯이 JS에서 var로 선언한 변수의 범위가 중괄호의 시작 및 끝 범위라고 성급히 생각할 수는 없습니다. 범위. 본질은 함수 범위입니다. ES6에서는 let과 const를 정의한 후에 블록 수준 범위가 있습니다.


Chestnut 5

function p1() { 
    console.log(1);
}
function p2() { 
    console.log(2);
}
(function () { 
    if (false) {
        function p1() {
            console.log(3);
        }
    }else{
        function p2(){
            console.log(4)
        }
    }
    p2();
    p1()
})();       
//4
//TypeError: print is not a function

아주 고전적인 밤나무 입니다. 미리 선언해 놨는데 판단 조건이 No라서 함수 본문이 실행되지 않습니다. 따라서 "TypeError: print is not a function"이 나타납니다. while, switch 및 for

클로저

에도 마찬가지입니다. 함수와 해당 상태에 대한 참조, 즉 어휘 환경(어휘 환경)이 함께 클로저를 형성합니다. 즉, 클로저를 사용하면 내부 함수에서 외부 함수 범위에 액세스할 수 있습니다. JavaScript에서 함수는 생성될 때마다 클로저를 생성합니다.

위 정의는 MDN에서 나온 것입니다. 간단히 말해서 클로저는 다른 함수의 범위에 있는 변수에 액세스하는 함수를 나타냅니다.


● 클로저의 핵심은 외부 함수가 호출된 후 변수 개체가 삭제되어야 한다는 것입니다. 하지만 클로저가 있으면 외부 함수의 변수 개체에 계속 액세스할 수 있습니다. ,

//举个例子
function makeFunc() {
    var name = "波妞";
    function displayName() {
        console.log(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

함수 JavaScript에서는 클로저를 형성합니다. 클로저는 함수와 함수를 생성하는 어휘 환경으로 구성됩니다. 이 환경에는 클로저가 생성될 때 액세스할 수 있는 모든 지역 변수가 포함되어 있습니다

예제에서 myFunc는 makeFunc가 실행될 때 생성된 displayName 함수 인스턴스에 대한 참조이며, displayName 인스턴스는 여전히 어휘 범위의 변수에 액세스할 수 있습니다. 이름에 액세스할 수 있습니다. 따라서 myFunc가 호출되면 name에 계속 액세스할 수 있으며 해당 값 'Ponyo'가 console.log에 전달됩니다. 클로저를 만드는 가장 일반적인 방법은 함수 안에 또 다른 함수를 만드는 것입니다


● 일반적으로 함수 실행이 끝나면 함수의 범위와 모든 변수가 소멸됩니다. 그러나 클로저가 생성된 후에는 클로저가 더 이상 존재하지 않을 때까지 함수의 범위가 저장됩니다.

//例二
function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

//释放对闭包的引用
add5 = null;
add10 = null;

본질적으로 makeAdder는 함수 팩토리입니다. 그는 지정된 값과 매개변수의 합계를 더하는 함수를 생성합니다. 위의 예에서는 함수 팩토리를 사용하여 두 개의 새로운 함수를 만들었습니다. 하나는 인수에 5를 더하고 다른 하나는 10을 더하는 함수입니다.

add5와 add10은 모두 클로저입니다. 이들은 동일한 함수 정의를 공유하지만 서로 다른 어휘 환경을 저장합니다. add5의 맥락에서 x는 5입니다. 그리고 add10에서 x는 10입니다.

클로저의 범위 체인에는 자체 범위뿐만 아니라 이를 포함하는 함수의 범위와 전역 범위도 포함됩니다.


● 클로저는 포함된 함수에 있는 모든 변수의 마지막 값만 얻을 수 있습니다.

//栗子1
function arrFun1(){
    var arr = [];
    for(var i = 0 ; i < 10 ; i++){
        arr[i] = function(){
            return i
        }
    }
    return arr
}
console.log(arrFun1()[9]());     //10
console.log(arrFun1()[1]());     //10

//栗子2
function arrFun2(){
    var arr = [];
    for(var i = 0 ; i < 10 ; i++){
        arr[i] = function(num){
            return function(){
                return num
            };
        }(i)
    }
    return arr
}
console.log(arrFun2()[9]());     //9
console.log(arrFun2()[1]());     //1

Chestnut 1에서 arr 배열에는 10개의 익명 함수가 포함되어 있으며 각 함수는 외부 변수 i, arrFun1에 액세스할 수 있습니다. 실행 후 범위는 는 소멸되었지만 해당 변수는 여전히 메모리에 존재하며 루프의 익명 함수로 액세스할 수 있습니다. 이 경우 i는 10입니다. Chestnut 2에는 arr 배열에 익명 함수가 있으며 해당 익명 함수가 있습니다. 가장 안쪽의 익명 함수가 접근한 num은 상위 익명 함수에 의해 메모리에 저장되므로 매번 i 값에 접근할 수 있습니다.

이 기사는 js 튜토리얼 칼럼에서 가져온 것입니다. 학습을 환영합니다!

위 내용은 js 범위 및 클로저에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 博客园에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
switch case 内变量的范围switch case 内变量的范围Feb 09, 2024 am 09:00 AM

packagemainimport"fmt"funcmain(){x:=10switchx{case0:y:='a'fmt.Printf("%c\n",y)case1://y='b'//thiscan'tcompile,y:='b'fmt.Printf("%c\n",y)default:y:=

Linux多线程编程锁详解:如何避免竞争和死锁Linux多线程编程锁详解:如何避免竞争和死锁Feb 11, 2024 pm 04:30 PM

在Linux多线程编程中,锁是一种非常重要的机制,可以避免线程间的竞争和死锁。然而,如果不正确使用锁,可能会导致性能下降和不稳定的行为。本文将介绍Linux中的常见锁类型,如何正确使用它们,以及如何避免竞争和死锁等问题。在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为”互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。Linux实现的互斥锁机制包括POSIX互斥锁和内核互斥锁,本文主要讲POSIX互斥锁,即线程间互斥锁。信号量用在多线程

详解Golang函数中的变量作用域详解Golang函数中的变量作用域Jan 18, 2024 am 08:51 AM

Golang函数中的变量作用域详解在Golang中,变量的作用域指的是变量的可访问范围。了解变量的作用域对于代码的可读性和维护性非常重要。在本文中,我们将深入探讨Golang函数中的变量作用域,并提供具体的代码示例。在Golang中,变量的作用域可以分为全局作用域和局部作用域。全局作用域指的是在所有函数外部声明的变量,即在函数之外定义的变量。这些变量可以在整

Python Lambda表达式:让编程变得更轻松Python Lambda表达式:让编程变得更轻松Feb 19, 2024 pm 09:54 PM

pythonLambda表达式是一个小的匿名函数,它可以将一个表达式存储在变量中并返回它的值。Lambda表达式通常用于执行简单的任务,这些任务可以通过编写一个单独的函数来完成,但Lambda表达式可以使代码更简洁和易读。Lambda表达式的语法如下:lambdaarguments:expressionarguments是Lambda表达式接收的参数列表,expression是Lambda表达式的体,它包含需要执行的代码。例如,以下Lambda表达式将两个数字相加并返回它们的和:lambdax,

掌握JavaScript函数的嵌套和作用域掌握JavaScript函数的嵌套和作用域Nov 03, 2023 pm 07:55 PM

掌握JavaScript函数的嵌套和作用域,需要具体代码示例在JavaScript编程中,函数是非常重要的概念。函数的嵌套和作用域能够极大地提高代码的可读性和灵活性。本文将介绍如何正确地使用嵌套函数和作用域,并提供具体的代码示例。函数的嵌套可以理解为在一个函数中定义了另一个函数。这种嵌套的方式能够将代码分成多个小块,使得程序的逻辑更加清晰。同时,嵌套函数还可

JavaScript const关键字的用法及作用JavaScript const关键字的用法及作用Feb 19, 2024 pm 06:30 PM

JavaScript中const的作用和用法JavaScript是一种广泛应用于网页开发的编程语言,其具有灵活性和动态性是其特点之一。在JavaScript中,我们可以使用const关键字来声明一个常量。本文将介绍const关键字的作用和用法,并提供一些具体的代码示例来帮助读者更好地理解。const的作用const(常量)是一种用于声明不可更改的变量的关键字

c语言static的作用和用法是什么c语言static的作用和用法是什么Jan 31, 2024 pm 01:59 PM

c语言static的作用和用法:1、变量作用域;2、生命周期;3、函数内部;4、修饰全局变量;5、修饰函数;6、其他用途;详细介绍:1、变量作用域,当一个变量前有static关键字,那么这个变量的作用域被限制在声明它的文件内,也就是说,这个变量是“文件级作用域”,这对于防止变量的“重复定义”问题很有用;2、生命周期,静态变量在程序开始执行时初始化一次,并在程序结束时销毁等等。

如何解决Python的变量未定义错误?如何解决Python的变量未定义错误?Jun 24, 2023 pm 10:12 PM

Python是一种高级编程语言,它的易用性和流行程度使得它成为了众多程序员的首选语言。与其他语言一样,Python也存在一些常见的错误类型,例如变量未定义错误。当我们在Python中使用一个未定义的变量时,程序就会抛出一个名为“NameError”的异常。这种错误通常出现在以下几种情况下:拼写错误:可能是因为变量名拼写错误导致了变量未定义错误,我们需要仔细检

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기