찾다
웹 프론트엔드JS 튜토리얼me_javascript 기술을 통해 자바스크립트 클로저 배우기

자바스크립트 클로저란 정확히 무엇인가요?

1년 넘게 JavaScript를 사용해왔는데 클로저가 항상 혼란스럽습니다. 나는 클로저에 대한 지식을 차례로 접했고 클로저에 대한 이해가 부족하여 몇 가지 실수를 저질렀지만 최근에는 여전히 잘 이해되지 않습니다. 우연히 부록 A의 JavaScript 클로저에 대한 소개를 보다가 이해하기 쉽고 간단해서 부처님께 공양하기 위해 꽃을 빌려 정리했습니다.

1. 정의

클로저: 다른 함수의 범위에 있는 변수에 접근할 수 있는 함수를 말합니다. 클로저를 생성하는 일반적인 방법은 다른 함수 내에 함수를 생성하는 것입니다.

예시 바로가기

function a(){
 var i=0;
 function b(){
  alert(++i);
 }
 return b;
}
var c = a();
c();

이 코드에는 두 가지 특징이 있습니다.

1) 함수 b는 함수 a 안에 중첩되어 있습니다.
2) 함수 a는 함수 b를 반환합니다.

이런 식으로 var c=a()를 실행한 후 변수 c는 실제로 함수 b를 가리킵니다. c()를 다시 실행하면 i 값을 표시하는 창이 팝업됩니다(처음은 1입니다). 이 코드는 실제로 클로저를 생성합니다. 이유는 무엇입니까? 함수 a 외부의 변수 c는 함수 a 내의 함수 b를 참조하기 때문에 다음과 같습니다.
함수 a 내부의 함수 b가 함수 a 외부의 변수에 의해 참조되면 클로저가 생성됩니다.

클로저의 기능을 모르기 때문에 아직 클로저를 이해하지 못하는 것 같습니다.

2. 클로저의 기능은 무엇인가요?

간단히 말하면, 클로저의 기능은 a가 실행되고 반환된 후 a의 내부 함수 b의 실행이 a에 의존해야 하기 때문에 클로저가 Javascript의 가비지 수집 메커니즘 GC가 a가 점유한 리소스를 회수하는 것을 방지한다는 것입니다. 의 변수 이는 클로저의 역할에 대한 매우 간단한 설명입니다. 전문적이거나 엄격하지는 않지만 일반적인 의미는 클로저를 이해하는 데에는 단계별 프로세스가 필요하다는 것입니다.
위의 예에서 클로저의 존재로 인해 a의 i는 항상 함수 a가 반환된 후에 존재하므로 c()가 실행될 때마다 i는 1을 더한 후 경고되는 i 값이 됩니다.

그럼 a가 b가 아닌 다른 것을 반환한다면 상황은 완전히 달라집니다. 왜냐하면 a가 실행된 후 b는 a의 외부 세계로 반환되지 않고 a에 의해서만 참조되기 때문입니다. 이때 a는 b에 의해서만 참조됩니다. 따라서 함수 a와 b는 서로를 참조하지만 방해받지 않습니다. 외부 세계에서 참조됨), 함수 a 및 b는 GC에 의해 재활용됩니다. (Javascript의 가비지 수집 메커니즘은 나중에 자세히 소개하겠습니다.)

3. 클로저 속 미시세계

클로저와 함수 a와 중첩 함수 b 사이의 관계를 더 깊이 이해하려면 함수 실행 컨텍스트(실행 컨텍스트), 활성 객체(호출 객체), 범위(범위) 등 몇 가지 다른 개념을 도입해야 합니다. ) ), 범위 체인. 이러한 개념을 설명하기 위해 정의부터 실행까지 함수 a의 프로세스를 예로 들어 보겠습니다.

1) 함수 a를 정의할 때 js 인터프리터는 함수 a의 범위 체인을 a가 정의된 "환경"으로 설정합니다. a가 전역 함수인 경우 범위 체인에는 창 개체만 있습니다. .
2) 함수 a가 실행되면 a는 해당 실행 컨텍스트로 들어갑니다.
3) 실행 환경을 생성하는 과정에서 먼저 a, 즉 a의 범위에 범위 속성이 추가되며 해당 값은 1단계의 범위 체인입니다. 즉, a.scope=a의 범위 체인입니다.
4) 그런 다음 실행 환경은 활성 개체(호출 개체)를 생성합니다. 활성 개체도 속성은 있지만 프로토타입이 없고 JavaScript 코드에서 직접 액세스할 수 없는 개체입니다. 활성 개체를 만든 후 범위 체인의 맨 위에 활성 개체를 추가합니다. 이때 a의 범위 체인에는 a의 활성 개체와 창 개체라는 두 개체가 포함됩니다.
5) 다음 단계는 함수 a를 호출할 때 전달된 매개변수를 저장하는 활성 객체에 인수 속성을 추가하는 것입니다.
6) 마지막으로 함수 a의 모든 형식 매개변수와 내부 함수 b에 대한 참조를 a의 활성 개체에 추가합니다. 이번 단계에서는 함수 b의 정의가 완료되므로 3단계와 마찬가지로 함수 b의 스코프 체인은 b가 정의된 환경, 즉 a의 스코프에 설정된다.

이제 전체 함수 a의 정의부터 실행까지의 단계가 완료됩니다. 이때 a는 함수 b의 참조를 c에 반환하고 함수 b의 범위 체인에는 함수 a의 활성 개체에 대한 참조가 포함되어 있습니다. 이는 b가 a에 정의된 모든 변수와 함수에 액세스할 수 있음을 의미합니다. 함수 b는 c에 의해 참조되고 함수 b는 함수 a에 의존하므로 함수 a는 반환 후 GC에 의해 재활용되지 않습니다.

b 함수가 실행되면 위의 단계와 동일합니다. 따라서 실행 중 b의 범위 체인에는 b의 활성 개체, a의 활성 개체 및 창 개체의 세 가지 개체가 포함됩니다. 함수 b의 변수에 액세스할 때 검색 순서는 해당 개체가 존재하는 경우 먼저 검색하는 것입니다. 존재하지 않으면 함수 a의 활성 개체를 찾을 때까지 계속 검색합니다. 전체 범위 체인에서 찾을 수 없으면 정의되지 않은 값이 반환됩니다. 함수 b에 프로토타입 프로토타입 객체가 있는 경우 먼저 자신의 활성 객체를 검색한 후 자신의 프로토타입 객체를 검색한 다음 계속 검색합니다. 이것은 Javascript의 변수 조회 메커니즘입니다.

4. 폐쇄 적용 시나리오

1) 함수 내 변수의 보안을 지켜주세요. 초기 예를 들어, 함수 a의 i는 함수 b를 통해서만 접근할 수 있고 다른 수단으로는 접근할 수 없으므로 i의 보안이 보호됩니다.
2) 메모리에 변수를 유지합니다. 이전 예제와 마찬가지로 클로저로 인해 함수 a의 i는 항상 메모리에 존재하므로 c()가 실행될 때마다 i는 1씩 증가합니다.
위의 두 가지 사항은 클로저의 가장 기본적인 적용 시나리오이며 많은 고전적인 사례가 여기에서 유래합니다.

5. 자바스크립트 가비지 수집 메커니즘

Javascript에서 객체가 더 이상 참조되지 않으면 해당 객체는 GC에 의해 재활용됩니다. 두 객체가 서로를 참조하고 더 이상 제3자가 참조하지 않는 경우, 서로를 참조하는 두 객체도 재활용됩니다. 함수 a는 b에 의해 참조되고 b는 a 외부의 c에 의해 참조되기 때문에 함수 a는 실행 후 재활용되지 않습니다.

在javascript中没有块级作用域,一般为了给某个函数申明一些只有该函数才能使用的局部变量时,我们就会用到闭包,这样我们可以很大程度上减少全局作用域中的变量,净化全局作用域。

使用闭包有如上的好处,当然这样的好处是需要付出代价的,代价就是内存的占用。

如何理解上面的那句话呢?

每个函数的执行,都会创建一个与该函数相关的函数执行环境,或者说是函数执行上下文。这个执行上下文中有一个属性 scope chain(作用域链指针),这个指针指向一个作用域链结构,作用域链中的指针又都指向各个作用域对应的活动对象。正常情况,一个函数在调用开始执行时创建这个函数执行上下文及相应的作用域链,在函数执行结束后释放函数执行上下文及相应作用域链所占的空间。

//声明函数
function test(){
 var str = "hello world";
 console.log(str);
}
//调用函数
test();

在调用函数的时候会在内存中生成如下图的结构:

但是闭包的情况就有点特殊了,由于闭包函数可以访问外层函数中的变量,所以外层函数在执行结束后,其作用域活动对象并不会被释放(注意,外层函数执行结束后执行环境和对应的作用域链就会被销毁),而是被闭包函数的作用域链所引用,直到闭包函数被销毁后,外层函数的作用域活动对象才会被销毁。这也正是闭包要占用内存的原因。

所以使用闭包有好处,也有坏处,滥用闭包会造成内存的大量消耗。

使用闭包还有其他的副作用,可以说是bug,也可以说不是,相对不同的业务可能就会有不同的看法。

这个副作用是闭包函数只能取到外层函数变量的最终值。

测试代码如下:(这里使用了jquery对象)

 /*闭包缺陷*/
 (function($){
  var result = new Array(),
  i = 0;
  for(;i<10;i++){
   result[i] = function(){
    return i;
   };
  }
  $.RES1 = result;
 })(jQuery);
 // 执行数组中的函数
 $.RES1[0]();

上面的代码先通过匿名函数表达式开辟了一块私有作用域,这个匿名函数就是我们上面所说的外层函数,该外层函数有一个参数$,同时还定义了变量result和 I , 通过for循环给数组result赋值一个匿名函数,这个匿名函数就是闭包,他访问了外层函数的变量I , 理论上数组resulti 会返回相应的数组下标值,实际情况却不如所愿。

如上代码 $.RES10 的执行结果是10.

为什么会这样呢,因为i的最终值就是10.

下面我们通过下图来详细说明下,上面的那段代码执行时在内存中到底发生了什么:

那么这个副作用有没有办法可以修复呢?当然可以!

我们可以通过下面的代码来达到我们的预期。

 /*修复闭包缺陷*/
 (function($){
  var result = new Array(),
  i = 0;
  for(;i<10;i++){
   result[i] = function(num){
    return function(){
     return num;
    }
   }(i);
  }
  $.RES2 = result;
 })(jQuery);
 //调用闭包函数
 console.log($.RES2[0]());

上面的代码又在内存中发生了什么?我们同样用下面的一幅图来详细解释。看懂了上面的图,我们也就不难理解下面的图。

6.简单的例子

首先从一个经典错误谈起,页面上有若干个div, 我们想给它们绑定一个onclick方法,于是有了下面的代码

<div id="divTest">
 <span>0</span> <span>1</span> <span>2</span> <span>3</span>
</div>
<div id="divTest2">
 <span>0</span> <span>1</span> <span>2</span> <span>3</span>
</div>


$(document).ready(function() {
  var spans = $("#divTest span");
  for (var i = 0; i < spans.length; i++) {
   spans[i].onclick = function() {
    alert(i);
   }
  }
});

很简单的功能可是却偏偏出错了,每次alert出的值都是4,简单的修改就好使了

var spans2 = $("#divTest2 span");
$(document).ready(function() {
 for (var i = 0; i < spans2.length; i++) {
  (function(num) {
   spans2[i].onclick = function() {
    alert(num);
   }
  })(i);
 }
});

7.内部函数

让我们从一些基础的知识谈起,首先了解一下内部函数。内部函数就是定义在另一个函数中的函数。例如:

function outerFn () {
 functioninnerFn () {}
}

innerFn就是一个被包在outerFn作用域中的内部函数。这意味着,在outerFn内部调用innerFn是有效的,而在outerFn外部调用innerFn则是无效的。下面代码会导致一个JavaScript错误:

function outerFn() {
 document.write("Outer function<br/>");
 function innerFn() {
  document.write("Inner function<br/>");
 }
}
innerFn();//Uncaught ReferenceError: innerFn is not defined

不过在outerFn内部调用innerFn,则可以成功运行:

function outerFn() {
   document.write("Outer function<br/>");
   function innerFn() {
    document.write("Inner function<br/>");
   }
   innerFn();
  }
  outerFn();

8、伟大的逃脱(内部函数如何逃脱外部函数)

JavaScript允许开发人员像传递任何类型的数据一样传递函数,也就是说,JavaScript中的内部函数能够逃脱定义他们的外部函数。

逃脱的方式有很多种,例如可以将内部函数指定给一个全局变量:

//定义全局变量逃脱
var globalVar;
function outerFn() {
 document.write("Outer function<br/>");   
 function innerFn() {
  document.write("Inner function<br/>");
 }
 globalVar = innerFn;
}
outerFn(); //Outer function Inner function
globalVar(); //Outer function Inner function
innerFn(); //ReferenceError: innerFn is not defined

调用outerFn时会修改全局变量globalVar,这时候它的引用变为innerFn,此后调用globalVar和调用innerFn一样。这时在outerFn外部直接调用innerFn仍然会导致错误,这是因为内部函数虽然通过把引用保存在全局变量中实现了逃脱,但这个函数的名字依然只存在于outerFn的作用域中。

也可以通过在父函数的返回值来获得内部函数引用

function outerFn() {
 document.write("Outer function<br/>");
 function innerFn() {
  document.write("Inner function<br/>");
 }
 return innerFn;
}
var fnRef = outerFn();
fnRef();

这里并没有在outerFn内部修改全局变量,而是从outerFn中返回了一个对innerFn的引用。通过调用outerFn能够获得这个引用,而且这个引用可以可以保存在变量中。

这种即使离开函数作用域的情况下仍然能够通过引用调用内部函数的事实,意味着只要存在调用内部函数的可能,JavaScript就需要保留被引用的函数。而且JavaScript运行时需要跟踪引用这个内部函数的所有变量,直到最后一个变量废弃,JavaScript的垃圾收集器才能释放相应的内存空间(红色部分是理解闭包的关键)。

说了半天总算和闭包有关系了,闭包是指有权限访问另一个函数作用域的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数,就是我们上面说的内部函数,所以刚才说的不是废话,也是闭包相关的 ^_^

9、变量的作用域

内部函数也可以有自己的变量,这些变量都被限制在内部函数的作用域中:

function outerFn() {
 document.write("Outer function<br/>");
 function innerFn() {
  var innerVar = 0;
   innerVar++;
   document.write("Inner function\t");
   document.write("innerVar = "+innerVar+"<br/>");
  }
  return innerFn;
}
  var fnRef = outerFn();
  fnRef();
  fnRef();
  var fnRef2 = outerFn();
  fnRef2();
  fnRef2();

每当通过引用或其它方式调用这个内部函数时,就会创建一个新的innerVar变量,然后加1,最后显示

Outer function
Inner function innerVar = 1
Inner function innerVar = 1
Outer function
Inner function innerVar = 1
Inner function innerVar = 1

内部函数也可以像其他函数一样引用全局变量:

var globalVar = 0;
function outerFn() {
 document.write("Outer function<br/>");
 function innerFn() {
  globalVar++;
  document.write("Inner function\t");
  document.write("globalVar = " + globalVar + "<br/>");
 }
 return innerFn;
}
 var fnRef = outerFn();
 fnRef();
 fnRef();
 var fnRef2 = outerFn();
 fnRef2();
 fnRef2();

现在每次调用内部函数都会持续地递增这个全局变量的值:

Outer function
Inner function globalVar = 1
Inner function globalVar = 2
Outer function
Inner function globalVar = 3
Inner function globalVar = 4

但是如果这个变量是父函数的局部变量又会怎样呢?因为内部函数会引用到父函数的作用域(有兴趣可以了解一下作用域链和活动对象的知识),内部函数也可以引用到这些变量

function outerFn() {
 var outerVar = 0;
 document.write("Outer function<br/>");
 function innerFn() {
  outerVar++;
  document.write("Inner function\t");
  document.write("outerVar = " + outerVar + "<br/>");
 }
 return innerFn;
}
var fnRef = outerFn();
fnRef();
fnRef();
var fnRef2 = outerFn();
fnRef2();
fnRef2();

这一次结果非常有意思,也许或出乎我们的意料

Outer function
Inner function outerVar = 1
Inner function outerVar = 2
Outer function
Inner function outerVar = 1
Inner function outerVar = 2

我们看到的是前面两种情况合成的效果,通过每个引用调用innerFn都会独立的递增outerVar。也就是说第二次调用outerFn没有继续沿用outerVar的值,而是在第二次函数调用的作用域创建并绑定了一个一个新的outerVar实例,两个计数器完全无关。

当内部函数在定义它的作用域的外部被引用时,就创建了该内部函数的一个闭包。这种情况下我们称既不是内部函数局部变量,也不是其参数的变量为自由变量,称外部函数的调用环境为封闭闭包的环境。从本质上讲,如果内部函数引用了位于外部函数中的变量,相当于授权该变量能够被延迟使用。因此,当外部函数调用完成后,这些变量的内存不会被释放(最后的值会保存),闭包仍然需要使用它们。

10.闭包之间的交互

当存在多个内部函数时,很可能出现意料之外的闭包。我们定义一个递增函数,这个函数的增量为2

function outerFn() {
  var outerVar = 0;
  document.write("Outer function<br/>");
  function innerFn1() {
   outerVar++;
   document.write("Inner function 1\t");
   document.write("outerVar = " + outerVar + "<br/>");
  }

  function innerFn2() {
   outerVar += 2;
   document.write("Inner function 2\t");
   document.write("outerVar = " + outerVar + "<br/>");
  }
  return { "fn1": innerFn1, "fn2": innerFn2 };
}
var fnRef = outerFn();
fnRef.fn1();
fnRef.fn2();
fnRef.fn1();
var fnRef2 = outerFn();
fnRef2.fn1();
fnRef2.fn2();
fnRef2.fn1();

我们映射返回两个内部函数的引用,可以通过返回的引用调用任一个内部函数,结果:

Outer function
Inner function 1 outerVar = 1
Inner function 2 outerVar = 3
Inner function 1 outerVar = 4
Outer function
Inner function 1 outerVar = 1
Inner function 2 outerVar = 3
Inner function 1 outerVar = 4

innerFn1和innerFn2引用了同一个局部变量,因此他们共享一个封闭环境。当innerFn1为outerVar递增一时,久违innerFn2设置了outerVar的新的起点值,反之亦然。我们也看到对outerFn的后续调用还会创建这些闭包的新实例,同时也会创建新的封闭环境,本质上是创建了一个新对象,自由变量就是这个对象的实例变量,而闭包就是这个对象的实例方法,而且这些变量也是私有的,因为不能在封装它们的作用域外部直接引用这些变量,从而确保了了面向对象数据的专有性。

11.解惑
现在我们可以回头看看开头写的例子就很容易明白为什么第一种写法每次都会alert 4了。

for (var i = 0; i < spans.length; i++) {
 spans[i].onclick = function() {
  alert(i);
 }
}

위 코드는 페이지가 로드된 후 실행됩니다. i 값이 4이면 판단 조건이 성립되지 않고 for 루프가 실행됩니다. 왜냐하면 각 범위의 onclick 메서드는 에서 내부 함수이기 때문입니다. 이번에는 i가 닫힙니다. 참조(클로저 참조가 참조를 전달함), 메모리는 제거될 수 없으며 i의 값은 4로 유지되며 프로그램이 이를 변경하거나 모든 onclick 기능이 제거될 때까지 재활용되지 않습니다(활성 할당) 함수를 null로 설정하거나 페이지가 언로드됩니다). 이런 식으로, 범위를 클릭할 때마다 onclick 함수는 i 값(범위 체인은 참조 방법임)을 조회하고, 이 값이 4와 같으면 경고합니다.

두 번째 방법은 즉시 실행되는 함수를 사용하여 클로저 레이어를 만드는 것입니다. 함수 선언은 괄호 안에 넣어서 표현식이 됩니다. 이때, 매개변수 i가 호출됩니다. 이 전달되면 함수는 즉시 실행되고 num은 매번 i의 값을 저장합니다.

이 글을 읽고 나면 누구나 저처럼 클로저에 대해 어느 정도 이해하고 있을 것입니다. 물론 클로저를 완전히 이해하려면 함수의 실행 환경과 범위 체인을 이해해야 합니다.

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

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

브라우저 너머 : 실제 세계의 JavaScript브라우저 너머 : 실제 세계의 JavaScriptApr 12, 2025 am 12:06 AM

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Apr 11, 2025 am 08:23 AM

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Apr 11, 2025 am 08:22 AM

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript : 웹 언어의 다양성 탐색JavaScript : 웹 언어의 다양성 탐색Apr 11, 2025 am 12:01 AM

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 진화 : 현재 동향과 미래 전망JavaScript의 진화 : 현재 동향과 미래 전망Apr 10, 2025 am 09:33 AM

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

Demystifying JavaScript : 그것이하는 일과 중요한 이유Demystifying JavaScript : 그것이하는 일과 중요한 이유Apr 09, 2025 am 12:07 AM

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.

Python 또는 JavaScript가 더 좋습니까?Python 또는 JavaScript가 더 좋습니까?Apr 06, 2025 am 12:14 AM

Python은 데이터 과학 및 기계 학습에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명하며 데이터 분석 및 웹 개발에 적합합니다. 2. JavaScript는 프론트 엔드 개발의 핵심입니다. Node.js는 서버 측 프로그래밍을 지원하며 풀 스택 개발에 적합합니다.

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에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

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

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구