이것은 무엇보다 혼란 스럽지만 기본적으로 코드는 DOM의 요소에 자식 요소를 재귀 적으로 추가합니다. 이는 클로저에 변수 "결과"가 정의되어 있기 때문에 가능합니다. 그 변수는 그 범위 내에서 살아 있습니다.
여기에 자바 스크립트의 변수 범위를 설명하는 몇 가지 테스트를 보여주는 기사가 있습니다. 여기에있는 것처럼 폐쇄에 대해 이야기하지 않는다는 점을 명심하십시오. 그러나 당신이 달려들 다른 것들을 설명하는 데 도움이 될 수 있습니다.
http://www.computerhowtoguy.com/an-introduction-to-javascript-variable-scope/
이 처리는 단계적으로 설명한다 다음 창로드 함수
- 코드는 "윈도우"레벨 범위를 가질 것이다. "this"를 출력한다면 "window" 객체를 얻을 수 있습니다.
- onload 함수는 "test"를 호출합니다. "test"( this.test 또는 window.test라고 쓰여 있음)가 닫힙니다. 이유는 그것이 인데,이 줄 때문에 클로저의 "test"함수는 다음과 같습니다. this.test = ... 클로저가 창 수준에서 실행되었으므로 "this"는 "window"개체를 참조합니다.
- "test"함수 호출에서 "this"는 "window"객체를 참조합니다. 위의 assert 함수는 this.assert = ... (window.assert)로 정의되었으므로 창 객체 수준에 있습니다. == window.assert를 선언했다면, 둘 다 같은 (함수) 객체에 대한 두 개의 이름이기 때문에 "true"가됩니다.
- 이 줄은 다음과 같이 실행됩니다. assert(). appendChild (document.createElement ("ul")) assert 함수는 그 뒤에 오는 항목보다 먼저 실행됩니다. 그럼 어설 션 코드로 들어가 ...
- "this"는 여전히 "창"개체입니다.로컬 변수 "li" 이 작성되어 문서 요소에 아직 첨부되지 않은 새 DOM 요소를 참조합니다 ( ). 그런 다음이 새로운 li 요소를 에 "결과"DOM 요소에 추가합니다. 이제 DOM 개체의 일부입니다. li 요소에 대한 자바 스크립트 참조가 반환됩니다.
- 이제 assert(). appendChild (document.createElement ("ul")) appendChild 함수가 호출되어 새로 작성된 'li'요소 에 'ul'요소를 추가합니다. 다음으로, 우리의 javascript "results"객체는 다시 한번 새로 할당 된 입니다. 이번에 새로 생성 된 ul 요소입니다. 마지막으로, 'fn'(우리의 익명 함수가 돌아왔다)이 호출됩니다.
- "fn"... "this"는 여전히 윈도우를 참조합니다. assert가 호출되면, 여전히 assert가 window.assert 함수에 대한 참조가됩니다. 새로운 li 요소가 생성되어 "results"변수에 추가됩니다. Rememeber, "결과"가 할당 된 마지막 항목은 ul 요소 였으므로 여기에 새로운 li을 추가합니다.
DOM 구조 것 같은이 시점 모습 뭔가 :
<div id="results">
<li>
<ul>
<li></li>
</ul>
</li>
</div>
그래서 코드가 물건의 같은 종류로 이동합니다 ...이 코드가 개정
, 지금 의견이 있습니다 :
// the following is a closure. a sort of isolated container with its own scope.
(function() {
// results is not globally scoped, only scoped at the closure level,
// since its defined with "var".
var results;
// "this" is the calling object. (ie: window object)
this.assert = function assert() {
// since "var" is used "li" is part of this function.
var li = document.createElement("li");
// results (at the closure level) appends a child at this function's level.
results.appendChild(li);
// return a javascript reference to the new DOM element.
return li;
};
// again "this" is the calling object. when called in onload below, "this" is the window object.
this.test = function test(name, fn) {
// results refers to the closure level results variable, since var is ommitted.
// this is a reference to an element in the DOM.
results = document.getElementById("results");
// changing the variable now. the DOM object "results" is NOT altered by this assignment, since
// javascript is separate from the DOM.
// NOTE: the assert function was previously assigned to the window object previously. so stuff in that
// function will be window scoped.
results = assert().appendChild(document.createElement("ul"));
// call fn
fn();
};
})();
window.onload = function() {
// at this point, "this" is the "window" object.
// "test" is part of the closure above. in the closure the test function is assigned
// to "this". since we are calling the function here, "this" will be the window object in the
// closure for this call.
test("A test.",
// an anonymous function. this is really just an object passed into the "test" function
function() {
assert();
assert();
}
);
};
네,하지만 왜 fn() 함수를 입력 할 때 결과 변수의 값이 다른가요? – user1512966
그 시점에서 왜 다른 가치가 있다고 생각합니까? – ThiefMaster
! 나는 그 문제를 발견했다. 문제는 fn() 함수에서 변수 결과가 표시되지 않는다는 것입니다. 그것은 "테스트"와 "assert"기능에서만 볼 수 있지만 HTML에서 "결과"를 "id"로 가지는 ul 요소가 있고 방화 광구에서 결과를 가리키면이 "id"값을 봅니다 마우스로 변수. – user1512966