무시되기 쉬운 JS 스크립트 기능

3877 단어
1. 무시되기 쉬운 국부 변수
 
  
var a = 5;
(function(){
alert(a);
var a = a ++;
alert(a);
})()
alert(a);

이 코드의 집행 결과를 생각하다.
실행한 후에 네가 상상한 것과 일치하는지 보아라.
ok, 이 코드의 핵심 지식점은var a=a++이다. 그 중에서 두 변수 a는 모두 익명 함수 내부의 국부 변수로 동일하며 전체 변수 a와 다르다.
왜?ECMA 사양의 변수 선언문 정의를 살펴보겠습니다.
 
  
Description
If the variable statement occurs inside a FunctionDeclaration, the
variables are defined with function-local scope in that function, as
described in s10.1.3. Otherwise, they are defined with global scope
(that is, they are created as members of the global object, as described
in 10.1.3) using property attributes { DontDelete }. Variables are
created when the execution scope is entered. A Block does not define a new
execution scope. Only Program and FunctionDeclaration produce a new
scope. Variables are initialised to undefined when created. A variable with
an Initialiser is assigned the value of its AssignmentExpression when the
VariableStatement is executed, not when the variable is created.

성명에서 언급한 바와 같이, 작용역 환경에 들어가면 변수가 생성되고, 초기값undefined가 부여됩니다.변수 성명문이 실행될 때만 이 변수에 할당 표현식의 값을 할당할 수 있으며, 이 변수가 생성될 때가 아닙니다.
따라서 위의 코드는 다음과 같습니다.
 
  
var a;
a = 5;
(function(){
var a;
alert(a);
a = a ++;
alert(a);
})()
alert(a);

이렇게 하면 더욱 쉽게 이해할 수 있을 것이다.
2. 무시되기 쉬운 전역 변수
 
  
(function(){
var a = b = 5;
})()
alert(b);

이것은 옥백이 며칠 전에 공유한 지식점으로 매우 의미가 있는데 여기서도 분석을 한다.
우선, 집행 결과가 왜 5인지 고려한다.
ok, 원인은 var a = b = 5라는 구절에서 나온다.
이 문을 심도 있게 분석하려면 계속해서 선언문에 대한 ECMA 사양의 정의를 참조합니다.
var a = b = 5;var a와 같습니다.a = b = 5;ECMA에서 정의된 값 지정 표현식인 두 문.
 
  
Simple Assignment ( = )
The production AssignmentExpression : LeftHandSideExpression =
AssignmentExpression is evaluated as follows:
1. Evaluate LeftHandSideExpression.
2. Evaluate AssignmentExpression.
3. Call GetValue(Result(2)).
4. Call PutValue(Result(1), Result(3)).
5. Return Result(3).

a=b=5에 대해먼저 왼쪽 표현식 a를 실행합니다. 이것은 규범 10.1.4에 따라 다음과 같은 표지 표현식입니다.
 
  
During execution, the syntactic production PrimaryExpression : Identifier
is evaluated using the following algorithm:
1. Get the next object in the scope chain. If there isn't one, go to step 5.
2. Call the [[HasProperty]] method of Result(1), passing the Identifier as
the property.
3. If Result(2) is true, return a value of type Reference whose base
object is Result(1) and whose property name is the Identifier.
4. Go to step 1.
5. Return a value of type Reference whose base object is null and whose
property name is the Identifier.

작용역 체인을 찾아서 가장 가까운 a의 인용을 찾으면 익명 함수 내부의 작용역에서 찾을 수 있기 때문에 변수 a가 확정된다.
이어서 오른쪽 표현식 b=5를 실행합니다. 또한 값 부여 표현식입니다. 값 부여 규칙을 반복하는 첫 번째 단계입니다. 변수 b가 익명 함수 환경에서 성명되지 않았기 때문에, 이어서 window 전역 환경에서 window를 찾습니다.b, 전역 변수로 은밀하게 성명되고 마지막에 5를 부여하며 규칙 5단계에 따라 표현식의 결과도 a에게 다시 부여된다.최종적으로 a와 b는 모두 5이고 차이는 a는 국부 변수이며 b는 전체 변수이다.
(function () {var a = b = 5} () 표현식 내부의 전체적인 실행 순서를 다시 한 번 정리해 봅시다.
1. 익명 함수에 변수 a 만들기;
2. 초기값undefined 부여;
3. 변수 a의 인용을 얻는다.//a
4. 변수 b의 인용 얻기;//window.b
5. 숫자 5에 대해 값을 구한다.
6. 값 5를 b에 부여하는 인용: window.b;
7. b=5의 결과 5를 a에 대한 인용: a;
8. a=5의 결과 5로 되돌아간다.
분명히 중간의 한 단계에서 변수 b를 전역 변수로 성명했다. 이해한 후에 우리는 코드의 최적화점을 찾기 어렵지 않다. 변수 b를 국부 변수로 명시하기만 하면 된다.
 
  
(function(){
var a,b;
a = b = 5;
})()

좋은 웹페이지 즐겨찾기