>웹 프론트엔드 >JS 튜토리얼 >javascript 함수 및scope_javascript 기술 요약 소개

javascript 함수 및scope_javascript 기술 요약 소개

WBOY
WBOY원래의
2016-05-16 17:16:131061검색

js에서 함수를 사용할 때 주의할 점:

1. 함수가 호출되면 선언된 구문 환경에서 실행됩니다.

2. 함수는 자체적으로 실행될 수 없습니다. 함수가 실행 중일 때 함수 본문의 this 포인터는 개체가 명시적으로 지정되지 않은 경우를 가리킵니다. 함수를 호출하면 기본적으로 창을 가리킵니다(엄격한 제외 모드, 이 문서에서는 엄격 모드를 다루지 않습니다).

3. 함수는 실행 가능한 코드가 포함된 객체형 데이터입니다.

1. 함수 선언

1. 함수 키워드를 사용하세요

코드를 복사하세요 코드는 다음과 같습니다.
function myfun(a,b){ //myfun이라는 함수 선언
b를 돌려주세요;

}



2. 익명함수 선언 function(a,b){ return a b;} 익명 함수 자체는 저장할 수 없습니다. 함수는 js의 일종의 객체 데이터이므로 익명 함수를 변수에 할당하여 저장할 수 있습니다.

var myfun = function(a,b){ return a b;}



3. 함수 생성자 사용 Function //첫 번째 문자는 대문자입니다.

Function은 js에 내장된 함수입니다. 모든 함수 객체의 생성자입니다. (다른 데이터 객체에도 Number, Object 등과 같은 자체 내장 생성자가 있습니다. 이러한 생성자의 생성자는 모두 함수이므로 Function입니다.)

var myfun = new Function('a,b','return a b;'); 마지막 매개변수는 함수 본문이고 이전 매개변수는 문자열이므로 숫자는 가변적입니다. 매개변수를 전달하여 구성합니다. 이 작성 방법은 함수가 길 때 매우 불편하며 eval 함수를 대체하기 위해 특정 반환 값을 구성하는 데 사용할 수도 있습니다.

전역 변수와 전역 함수 모두 창 객체의 속성으로 간주할 수 있다는 점에 유의하세요. 동일한 이름의 함수와 변수가 있으면 하나만 적용됩니다(실제로는 하나의 속성만 있습니다). 다음 코드.


코드 복사 코드는 다음과 같습니다.
function a(){ Alert('a ') }
alert(window.a); //창을 작성하지 않고도 창 개체의 속성에 액세스할 수도 있습니다.

var a=1;

alert(window.a);


코드 구문 분석 기간 동안 함수 및 변수 선언이 발생합니다. 차이점은 구문 분석 기간 동안 변수가 선언되기만 하고 값이 할당되지 않는다는 것입니다. 따라서 동일한 범위 내에서 동일한 이름의 함수와 변수가 있는 경우, 코드 실행 중 변수가 할당되기 전에 동일한 이름의 변수가 할당된 후(원래 이름)가 적용됩니다. 창 개체 속성의 값이 새 데이터로 덮어쓰기됨), 변수가 적용됩니다(그러나 Firefox에서는 의사 클로저를 사용하여 선언된 함수는 선언 후에만 호출할 수 있습니다. Firefox의 with에서 함수 선언).

코드 복사 코드는 다음과 같습니다.
with({}){
a() ; //firefox에서 a는 선언되지 않았습니다.
function a(){ console.log("function a is Called");}
}

동일한 이름이 호출됩니다. 여러 번 선언되면 이후 선언이 다음과 같이 이전 선언을 덮어씁니다.

alert(func1);//pop up func1(){alert(2);}
func1(){

경고(1);

}

alert(func1); //func1(){alert(2);}

팝업

func1(){ //이 함수는 마지막으로 선언된 func1입니다.

경고(2);

}

alert(func1); //func1(){alert(2);}

팝업

var func1 = function(){ //참고, 이는 함수 선언이 아니라 변수 할당입니다

경고(3);

}

alert(func1); //팝업 function(){alert(3);}


아래 IE8 및 브라우저를 제외하고 표현식의 함수 선언은 익명 함수를 반환합니다. 명명된 함수를 성공적으로 선언하지 못합니다.

코드 복사 코드는 다음과 같습니다.

if(function fun(){}){
Alert(fun); // 오류, fun이라는 함수는 성공적으로 선언되지 않지만 IE8 이하 브라우저에서는 성공합니다. 재미있는 기능

}

(함수 fun(){ });

alert(fun); //error 그러나 IE8에서도 표현식의 명명된 함수는 동일한 이름의 변수를 재정의할 수 없습니다.

var fun = 1; //이 변수는 함수 표현식의 함수 이름으로 덮어쓸 수 없습니다.
var f = function fun(){};
alert(f); { };
alert(fun); //1


차이점 참고:

if(fun = function (){}){
Alert(fun); // 좋아요, 익명 함수를 저장하는 변수가 여기에 선언되었습니다

}

js 함수는 참조 객체입니다

var a = function(){};
var b=a;
b.x=2;
alert(a.x) //2

2. 기능 매개변수

js 함수는 함수 호출 시 전달된 매개변수 개수와 정의 시 형식 매개변수 개수가 일치하는지 확인하지 않습니다. 일반적으로 js 함수 호출 시 수신할 수 있는 매개변수 개수입니다. 물론 다른 브라우징 프로세서는 다를 수 있으며 ECMAScript 표준은 이를 규제하지 않습니다.

함수를 호출할 때 몇 개의 매개변수가 전달되는지 확실하지 않은 경우 함수의 인수 개체를 사용할 수 있습니다.

arguments는 배열과 약간 유사합니다. 인수.길이는 전달된 매개변수의 수, 인수[0]은 첫 번째 매개변수, 인수[1]은 두 번째 매개변수 등입니다...

함수 객체의 길이 속성: 이 속성은 거의 사용되지 않으며, 함수 정의 시 함수의 길이 속성이 형식 매개변수의 개수라는 ​​사실조차 아는 사람은 거의 없습니다.

코드 복사 코드는 다음과 같습니다.

function myfun(a,b){

alert(arguments.length); //호출 팝업 시 전달된 실제 매개변수 수

alert(arguments[0]); //해당 매개변수 a

b를 돌려주세요;

}

alert(myfun.length); //형식 매개변수 수, 2


arguments 객체에는 함수 자체를 가리키는 일반적으로 사용되는 인수.callee와 같은 다른 속성도 있습니다.

참고: 함수 내부에 형식 매개변수와 동일한 이름의 하위 함수가 선언된 경우(동일한 범위에서는 변수에 값이 할당되지 않은 경우 동일한 이름의 함수가 적용됩니다.) 해당 인수의 값은 그러나 범위에서 var를 사용하여 동일한 이름을 선언하면 변수는 인수의 매개변수 값을 함수로 대체하지 않습니다(그러나 Firefox는 여전히 이를 대체합니다).

코드 복사 코드는 다음과 같습니다.

function aa(a, b,c) { // js 그룹의 질문
function a(){}

console.log(a) //function a
console.log(aa);

//범위에 var a가 없으면 인수[0]은 함수 a(friefox(버전 17))이므로 함수 a)
console.log(arguments[0]); 🎜> var a = "ee"; / /이 문장을 취소하면 테스트 인수[0]가 함수가 됩니다.
var aa = "444";
인수 = 6;
console.log(a) ;
console.log( aa);
console.log(인수);
}
aa(1,2,3)


3. 함수의 반환값 js 함수는 return 문을 사용하여 값을 반환합니다.

모든 데이터 유형은 함수(함수 포함)의 반환 값으로 사용될 수 있으며, js 함수도 반환 값이 없을 수 있습니다.

4. 함수 호출

함수 자체는 실행되지 않습니다. 실행되면 항상 이를 호출하는 개체가 있습니다.

기본적으로 모든 구문 환경에서는 함수의 호출 개체를 명시적으로 지정하지 않으면 창 개체를 통해 함수가 호출됩니다. 이때 함수 ​​본문의 this 포인터는 창 개체를 가리킵니다.


코드 복사 코드는 다음과 같습니다.
function myfun(a,b){
알림(이것);

b를 돌려주세요;

}

myfun(1,2); // 함수를 호출하고 각각 형식 매개변수 a와 b에 해당하는 2개의 매개변수를 전달합니다. 함수 호출 시 전달된 매개변수 수가 형식 매개변수를 초과하면 인수만 사용할 수 있습니다. 인수는 아래 첨자와 함께 수신됩니다.



함수를 호출하는 객체가 명시적으로 지정되지 않았기 때문에, Alert(this)는 윈도우 객체를 팝업시킵니다. 이 호출 방법이 가장 일반적입니다.

함수를 명시적으로 지정하기 위한 세 가지 호출 개체 메서드가 있습니다.

1. 함수가 객체의 속성값으로 할당된 경우 해당 객체를 통해서만 함수에 접근할 수 있습니다(단, 객체에서만 함수를 호출할 수 있다는 의미는 아닙니다). 객체를 통한 함수는 객체지향 프로그래밍 언어에서 메소드로 호출되는 것과 비슷합니다(실제로 js에서도 name 메소드를 사용하는 것이 관례입니다).

코드 복사 코드는 다음과 같습니다.

var obj={} //Define 객체

obj.fun=function(a,b){

alert(this); //이 포인터를 표시합니다

b를 돌려주세요;

} //객체 속성 값은 함수입니다

alert(obj.fun);//재미있는 기능에 접근합니다. 이 기능은 이 개체를 통해서만 접근할 수 있습니다

obj.fun(1,2); //obj 객체를 통해 fun 함수를 호출하면 obj 객체가 나타납니다. 이 메서드는 obj 객체의 fun 메서드 호출이라고도 합니다.


2. 함수 호출 객체를 임의로 지정: 특정 구문 환경에서 fun 함수와 obj 객체에 동시에 액세스할 수 있으면 fun 함수를 호출하도록 지정할 수 있습니다. 원한다면 obj 객체를 통해. 지정된 방법에는 호출 방법과 적용 방법의 두 가지가 있습니다. (window 객체는 브라우저 환경의 최상위 객체이기 때문에 어떤 구문 환경에서도 window 객체에 접근할 수 있으므로, window 객체를 통해서는 어떤 함수라도 호출할 수 있다)
코드 복사 코드는 다음과 같습니다.

function fun(a,b){

알림(이것);

b를 돌려주세요;

}

var obj={};

fun.call(obj,1,2); //obj 객체를 통해 fun 함수를 호출하고 2개의 매개변수를 전달합니다. 팝업 포인터는 obj 객체입니다.

var obj2={};

obj2.fun2 = function(a,b){ //obj2 객체의 fun2 속성은 함수입니다

경고(이것);

b를 돌려주세요;

};

obj2.fun2.call(obj,1,2); //obj 객체를 통해 obj2 객체의 fun2 속성 값에 저장된 함수를 호출합니다. 이 포인터는 obj 객체입니다

//상대적으로 숨겨진 메소드 호출: 배열이 함수를 호출합니다. [9, function(){ Alert(this[0]) }][1]();

//윈도우 객체를 사용하여 함수를 호출하는 다음 방법은 동일합니다.
fun(1,2);
window.fun(1,2) //fun 함수가 전역 함수인 경우
fun.call(window,1,2);
fun.call(this,1,2); //이 코드가 전역 환경에 있는 경우(또는 창 개체에 의해 호출되는 함수 본문 내에 있는 경우) 이 구문의 환경에서 이것은 창 개체를 가리킵니다.
func.call(); //함수가 매개변수를 전달할 필요가 없는 경우
func.call(null,1,2);
func.call(undefine,1,2);var name = "window";
function kkk(){
console.log(this.name); // 즉,
}
kkk() //window
kkk.call( kkk); //kkk 함수가 자체적으로 호출되었습니다


간과하기 쉬운 또 다른 오류는 객체 A의 메소드에서 객체 B를 사용한 메소드 호출이 실행되고 시도된다는 것입니다. 객체 B의 메소드를 사용하는 것은 다양한 콜백 함수에서 흔히 사용되는 A 객체에 액세스하는 데 사용됩니다. 가장 일반적인 상황은 ajax 콜백 함수에서 이것을 사용하는 것입니다.
코드 복사 코드는 다음과 같습니다.

var obj = {
data: null,
getData:function(){
$.post(url,{param:token},function(dataBack){ //jQuery ajax post method
this.data = dataBack; //다음을 시도 중입니다. 서버에서 데이터 반환 데이터는 obj.data에 할당되지만 여기서는 이미 jQuery
      },'json'의 ajax 객체를 가리킵니다.
//올바른 접근법
var obj = { data:null,

getData:function(){
var host = this; //obj 객체의 참조 저장
$.post(url,{param:"token"},function(dataBack){
                       호스트.데이터 = dataBack;
3. 적용 메소드 호출:

적용 방식과 호출 방식의 유일한 차이점은 함수 매개변수를 전달하는 방식입니다.

obj2.fun2.call(obj,1,2); 적용 방법 변경은 obj2.fun2.apply(obj,[1,2]);

apply는 배열과 유사한 메서드를 사용하여 매개변수를 전달합니다. 배열 외에도 인수와 HTMLCollection을 사용하여 매개변수를 전달할 수도 있지만 인수는 다음과 같이 배열이 아닙니다.

var obj={};

함수 fun_1(x,y){

함수 fun_2(a,b){

b를 반환합니다;

}

fun_2.apply(obj,arguments); //fun_1의 인수 객체를 사용하여 실제로 x, y를 받는 매개변수를 전달합니다

} IE8 및 IE8 이하 브라우저에서는 매개변수 적용 시 2가지 문제가 있습니다

호출 및 적용 호출에서 스칼라 데이터(true/false, 문자열, 숫자)가 전달되면 함수는 실행 시 전달된 기본 데이터를 객체로 래핑한 다음 이를 래핑된 객체를 가리킵니다. 아래 코드를 시도해 보세요.
함수 a(){

경고(이 유형);

경고(this.constructor);

알림(이것);

}

a.call(false);

a.call(100);

a.call('안녕하세요');

이 기능을 사용하여 매개변수를 전달할 수도 있지만 이 사용은 권장되지 않습니다.

function a(){ Alert(1 this) } //작업 중에 객체가 자동으로 유형 변환을 수행합니다

a.call(100) //101

4. 객체 생성자로서의 기능

함수가 new 연산을 객체 생성자로 사용하는 경우 this는 새로 생성된 객체를 가리킵니다. 생성자의 반환 값이 null 이외의 객체가 아닌 경우 생성자는 실행 후 this가 가리키는 객체를 반환합니다. 그렇지 않으면 원래 정의로 돌아갑니다.

코드 복사 코드는 다음과 같습니다.

function Fun(){

this.a = 1

this.b = 3;

console.log(this) //{a:1,b:2}

// return {a:999}; //이 단계에서는 {a:999}를 반환합니다.

}

var obj = new Fun(); //obj = {a:1,b:2}, 매개변수가 없으면 var obj = new Fun; 🎜>

5. 기능 범위
js의 변수 범위는 함수 수준에 있습니다. js에는 c 언어와 마찬가지로 블록 수준 범위가 없습니다. js 프로그래밍 환경의 최상위 범위는 전역 범위라고 하는 창 개체 아래의 범위입니다.

js 함수 내의 변수는 함수 외부에서 접근할 수 없지만, 함수 외부의 변수는 함수 내부에서 접근할 수 있습니다.

JS 함수는 중첩될 수 있습니다. 여러 함수를 중첩하는 것을 JS의 범위 체인이라고 합니다.

js 스코프 체인의 변수 접근 규칙은 접근하려는 변수가 현재 스코프에 존재하면 현재 스코프의 변수를 사용하고, 그렇지 않으면 전역 스코프까지 상위 스코프에서 검색하고, 찾지 못하면 변수를 사용하는 것입니다. 선언되지 않았습니다.

코드 파싱 기간 동안 변수 선언이 완료된다는 점에 유의하세요. 현재 범위의 변수 선언 및 대입문을 변수 액세스 문 다음에 작성하면 js 함수는 해당 변수에 이미 액세스한 것으로 간주합니다. 현재 범위에 존재하며 더 이상 상위 도메인 조회에 영향을 미치지 않습니다. 그러나 코드 런타임 중에 변수 할당이 발생하므로 액세스된 변수는 정의되지 않습니다.

예:


코드 복사 코드는 다음과 같습니다.var c= 1000;
함수 출력(){
var a=1;

var b=2;

fun() 함수{

경고(a) //정의되지 않음

var a=10;

경고(a) //10

경고(b) //2

경고(c) //1000

}

재미();

}

아웃()


6. 익명 함수 호출

js에서는 익명 함수의 사용이 매우 중요합니다. 함수를 포함하여 js의 모든 데이터는 객체이기 때문에 함수는 다른 함수의 매개변수나 반환값으로 사용되는 경우가 많습니다.

익명 함수를 저장하지 않으면 실행 후 메모리에서 해제됩니다.

익명 함수를 호출하는 방법은 함수 이름 대신 괄호 안에 익명 함수를 직접 넣는 것입니다. 예:

(function(a,b){ return a b;})(1,2); //런타임 중에 두 개의 매개변수 1과 2를 전달하여 익명 함수를 선언하고 실행합니다

//또는

(function(a,b){ return a b;}(1,2));

//다음 작성 방법이 잘못되었습니다.

function(a,b){ return a b;}(1,2)

js에서 문 끝의 세미콜론은 생략할 수 있으므로 js 엔진은 function(a,b){ return a b;}를 문의 끝으로 간주하므로 익명 함수는 선언만 하고 명령문이 ()로 작성된 매개변수(1,2)를 전달하지 않으면 js의 빈 괄호도 오류를 발생시킵니다.

다음과 같은 표기법이 맞습니다.

var ab = function(a,b){ return a b;}(1,2) // ab=3

js가 문법을 파싱할 때 할당 연산이나 연산자 연산에 표현식이 나타나면 '탐욕스러운 일치'입니다(최대한 평가해 보세요)

function(t){ return 1 t;}(); //오류
var f = function(t){ return t 1;}() // ok

~ function(t){return t 1;}(); //확인
function(t){return t 1;}() //확인

단지 변수에 익명 함수를 할당하려면 할당 문 뒤에 세미콜론을 추가해야 합니다. 그렇지 않으면 괄호가 뒤에 오면 특히 괄호와 끝 사이에 함수 호출이 됩니다. 이 오류는 여러 줄이 공백으로 구분되어 있으면 찾기 어려운 경우가 많습니다.

실제 개발에서는 익명 함수가 연산 값의 형태로 반환될 수 있습니다.

과 같이 이러한 상황은 쉽게 확인되지 않을 수 있습니다.

var a =1;
var obj = {a:2,f:function(){ return this.a;}};

(1,obj.f)(); //1 쉼표 표현식은 익명 함수를 반환합니다. 이 익명 함수가 호출되면 함수 본문의 thsi가 창을 가리킵니다.

익명 함수를 선언하고 즉시 실행하는 것을 "자체 실행 함수"라고 합니다. 자체 실행 함수는 종종 js 코드 조각을 캡슐화하는 데 사용됩니다. 함수 범위의 특성으로 인해 자체 실행 함수 내의 변수는 외부에서 접근할 수 없습니다. 함수 내에 배치된 코드는 외부 코드에 영향을 주지 않으므로 변수 오염을 피할 수 있습니다. JS 개발은 변수 오염을 쉽게 일으킬 수 있으며, 개발 중에 다른 코더가 개발한 코드가 도입되는 경우가 많습니다. 서로 다른 코더가 같은 이름을 가진 전역 변수나 함수를 정의하면 같은 이름의 변수가 같은 범위에 나타납니다. 또는 기능을 사용하는 경우 나중 기능이 이전 기능을 덮어씁니다.

(함수(){

//자신만의 코드....

})(); 익명 함수는 시간에 맞춰 메모리를 해제할 수도 있습니다. 변수는 익명 함수 내에서 선언되므로 이러한 변수가 익명 함수 외부에서 참조되지 않으면 함수 실행이 종료되고 내부 변수가 차지합니다. 메모리가 즉시 해제됩니다.

함수 이름: Firefox 등의 브라우저에서는 함수에 함수 이름인 name 속성이 있지만 IE에는 이 속성이 존재하지 않습니다. 또한 익명 함수의 이름은 다음과 같습니다. 비어 있는.

var a=function(){}

alert(a.name); //정의되지 않음, a는 익명 함수를 저장하는 변수입니다.
function b(){}
alert(b . 이름); //b, IE에서는 정의되지 않음

7. 함수가 호출되면 정의된 환경에서 실행됩니다.

함수를 어디서, 누구에 의해 호출하든 선언 시 구문 환경을 변경할 수 없으며, 이에 따라 함수의 실행 환경이 결정됩니다.


코드 복사 코드는 다음과 같습니다.

var x=99;

var inerFun=null;

fun1() 함수{

경고(x);

}

함수 홀더(){

var x = 100;

var fun2 = fun1;

inerFun = function(){ 경고(x);}

fun1() //99

fun2();//99

inerFun() //100

}

홀더();

재미1() //99

inerFun() //100

//또 다른 예:

var x = 100;
var y=77;
var a1={
x:99,
xx:function(){
//var y=88; /이 변수에 주석을 달면 y는 전역 변수가 됩니다. 77
Alert(y); //이 포인터가 없으면 함수를 호출하는 객체는 함수가 실행될 때 y의 값에 영향을 미칠 수 없습니다. 여기에서 범위 체인으로 이동합니다.
Alert(this.x) //이 포인터를 사용하여 함수 호출
}
}

a1.xx();
a1.xx.call(창);

var jj = a1.xx;

jj(); //효과는 a1.xx.call(window)와 동일합니다. //다음 코드를 사용해 보세요

var x=99;
function xb(){
this.x=100;
this.a = (function(){return this.x}).call(this); /new가 실행되고, 인스턴스화된 객체에 의해 익명 함수가 호출됩니다.
this.b = (function(){return this.x})() //new가 실행되고, 익명 함수가 window에 의해 호출됩니다.
this.method = function(){return this.x;}
}


var xbObj = new xb();
console.log(xbObj.x);
console.log(xbObj.a);
console.log(xbObj.b);
console.log(xbObj.method());


함수를 호출하는 객체의 개념, 함수가 선언될 때의 구문 환경, 함수 호출문

1. 함수를 호출하는 객체(또는 함수를 호출하는 방법)는 함수가 실행될 때 함수 본문의 this 포인터가 누구를 가리키는지 결정합니다.

2. 함수 선언 시의 구문 환경에 따라 함수 실행 시 접근 권한이 결정됩니다

3. 함수 호출문의 구문 환경에 따라 함수가 실제로 호출될 수 있는지 여부와 시기가 결정됩니다. (특정 구문 환경에서 함수가 표시되는 경우에만 이 함수를 호출할 수 있습니다.)

함수가 실행 중일 때 함수에 전달된 매개변수에 액세스하기 위해 인수 개체가 생성됩니다. 인수에는 함수 자체를 가리킬 수 있는 속성(args.callee)이 있습니다.

함수가 실행 중일 때 함수의 호출자 속성은 함수 호출 문이 있는 함수를 가리킬 수 있습니다. 예를 들어 함수 a가 함수 b의 본문 내에서 호출된 다음 함수 a가 실행 중일 때 a가 호출됩니다. .caller는 함수 b를 가리킵니다. 함수 a인 경우 전역 환경에서 호출되는 경우 a.caller=null

인수 및 a.caller의 값은 함수의 각 호출과 직접 관련되어 있으며 함수가 실행될 때 생성되며 함수 본문 내에서만 액세스할 수 있습니다.

IE8 이하 브라우저에서는 함수의 인수.caller(IE9 이후에는 이 속성이 제거됨)가 a.caller가 실행될 때 인수를 가리킵니다(arguments.caller.callee === a.caller).

7. 실시간 문자열 구문 분석의 함수 호출: eval(), new Function(), setTimeout(), setInterval()

eval() 및 window.eval()

코드 복사 코드는 다음과 같습니다.

function a(){
console.log('out of b');
}
function b(){
function a(){ console.log("in b" ); }
var f = function(){ a(); };
eval('a()'); // b
window.eval('a()'); /b 중 , 즉 b 중 678, 즉 b 중 9
(new Function('a();'))() //b 중
setTimeout('a()',1000 ); / / out of b
setTimeout(f,2000);// in b
}
b();

의 코드는 다음에서 실행됩니다. eval() 문 범위 내:
코드 복사 코드는 다음과 같습니다.

var Objinit = function(){
  var param = 123;
  return {
          실행:함수(코드){
               eval(codes);
          },
          setCallback:function(f){
              this.callback = f;
         },
         fireCallback:function(){
               this.callback && this.call back.call(this);
          },
         getParam:function(){
             return param;
         }
   }
};

var obj = Objinit();
var param = 'outerParam';
console.log(param,obj.getParam()); //outerParam 123
obj.execute('param = 456');
console.log(param,obj.getParam()); //outerParam 456
obj.setCallback(function(){ eval("param = 8888")});
obj.fireCallback();
console.log(param,obj.getParam()) ; //8888 456
obj.setCallback(function(){ eval("eval(param = 9999)")});
obj.fireCallback();
console.log(param,obj.getParam ()); //9999 456eval()


字符串中解析出的代码运에서 eval 所在的작용域,window.eval() 则是运行에서顶级작용域(低版本 chrome 와 低于IE9则同 eval()).

IE 中 ,window.execScript();  비교 window.eval()

new Function()、setTimeout()、setInterval()  的第一个字符串参数所解析得到的代码,tour是在顶级 창작域执行。

八、函数闭包

要理解函数闭包, 先了解 js 的垃圾自动回收机system.

숫자, 문자열, 부울, 정의되지 않음, null 에서 运算와 赋值操work中是复 제조사에서 值, 而对象类型的数据按引用传值,

js와 같은 동일한 유형의 js를 사용하는 경우가 많으며, 如果某个对象不再被引用, 或者两个对象の间互互互象间互互互象용으로 외부에서 사용할 수 없습니다. 사용하기内存空间。

函数被引用: 函数被赋为其他对象적 성격 유형, 或者函数内内数数数数数据에서 函数被赋为其他对象的属性值감정형。

复主代码 代码如下:

var f;

fun() 함수{

var a =1;

f = 함수(){ return a;};

}

재미(); //产生一个闭包

f(); //  闭包中 a=2

f(); // 闭包中 a =3  ,模拟静态变weight


재 재미 内 声명명명匿name匿数赋给 fun 외적变weight f,该匿name函数内使用了재 재미 内声명적 량 a,于是 f可以访问 变weight a,为了维持这种访问权限(f执 行时需要访问a,但何时执,行未定) 执行完毕生变weight不能被释放(除不f 中的函数被释放) ,于是产生了一个闭包(变weight a 被封 闭了,供 f 使用)。

产生闭包的关键是, 一个在函数 A内的声명명한函数 B被传出 A 之外,并且 B 函数内使用了在 函数A 内生成的数据(声明或按值传参),

函数B传出函数A는 외부 방식으로 매우 다양합니다.如:

复代码 代码如下:

function fun(){   
var a =1;

return {a:123,b:456, c: function(){ return a;} };

}

var f = fun();

f.c(); //a=2

广义上来说, 函数运行时city会shape成闭包,没有数据在函数外被引用时, 闭包的生命周期很短:函数执行完毕即释放。

闭包的独立性:即使由同一个函数产生的多个闭包也是互独立性

复代代码代码如下:

function fun(){

var a =1;

반환 함수(){ return a;};

}

var f1 =  fun(); //一份闭包

var f2 = fun(); //另一份闭包

경고(f1()); //2

 alert(f1()); //3

 alert(f2()); //2

 alert(f2()); //3


두 클로저의 변수 a는 서로 다른 데이터입니다. 클로저가 생성될 때마다 fun()이 한 번 실행되고, 변수 선언문도 한 번 실행됩니다.

js oop 프로그래밍에서 클로저를 사용하여 비공개 멤버를 시뮬레이션하고 단일 클래스를 구성할 수 있습니다

코드 복사 코드는 다음과 같습니다. 다음:

function MakeItem(name,val){
var myName,myVal; //개인 속성

//프라이빗 메소드
function setName(name){
myname=name
}

//프라이빗 메소드
function setVal(val){
myVal=val;
}

//객체를 구성하기 위해 new를 실행할 때 내부 전용 메소드를 호출합니다.
setName(name);
setVal(val);

//공용 메소드
this.getName=function(){
return myName;
this.getVal=function(){

return myVal;

}
}

var obj = new MakeItem("name",100);

obj.myname; //정의되지 않은 개인 속성은 외부에서 액세스할 수 없습니다.

obj.getName() //ok


다음은 싱글 클래스 구성 방법입니다



코드 복사 코드는 다음과 같습니다

var Singleton = (function(){

    var instance = null; //在闭包中保存单体类的实例

    var args = null;

    var f = function(){

        if(!instance){

            if(this===window){               

               args = Array.prototype.slice.call(arguments,0);               

                instance = new arguments.callee();

            }else{

               this.init.apply(this,args||arguments);

                instance = this;

            }

        }

        return instance;

    };

    f.prototype = {

        init:function(a,b,c){

            this.a = a;

            this.b = b;

            this.c = c;      

            this.method1 = function(){ console.log("method 1"); };

            this.method1 = function(){ console.log("method 1"); };

            console.log("init instance");

        }

    };

    f.prototype.constructor = f.prototype.init;

    return f;

 

})();


//单体的使用
var obj1 =  Singleton(1,2,3);

var obj2 = new Singleton();

var obj3 = new Singleton();

console.log(obj1===obj2,obj2===obj3); //true

console.log(obj1);

//一个单体类声明函数

var SingletonDefine= function(fun){

    return (function(){

        var instance = null;

        var args = null;      

        var f = function(){

            if(!instance){

                if(this===window){

                    args = Array.prototype.slice.call(arguments,0);                   

                    instance = new arguments.callee();

                }else{

                    fun.apply(this,args||arguments);                   

                    instance = this;

                }

            }

            return instance;

        };

 

        f.prototype = fun.prototype;

        f.prototype.constructor = fun;            

        return f;

    })();

};

var fun = function(a,b,c){

    this.a = a;

    this.b = b;

    this.c = c;

this.method1 = function(){ console.log("메서드 1");

console.log("init 인스턴스");

};

fun.prototype.method2 = function(){ console.log('메소드 2') };


//싱글 클래스 선언 함수 사용법
var Singleton = SingletonDefine(fun);

var obj1 = 싱글톤(8,9,10);

var obj2 = new Singleton();

var obj3 = new 싱글톤(3,2,1);

console.log(obj1===obj2,obj2===obj3);

console.log(obj1);

//console.log(obj1.toSource()) //firefox

obj1.method1();

obj1.method2();


IE6의 메모리 누수 및 종료

IE 6에서는 기본이 아닌 js 개체(DOM 등)에 대한 순환 참조로 인해 메모리 누수가 발생합니다. 클로저를 사용할 때는 js가 아닌 기본 개체 참조를 사용할 때 주의하세요.

fun() 함수{

var node = document.getElementById('a');
node.onclick = function(){ 경고(node.value) };

node = null; //메모리 누수를 방지하기 위해 순환 참조를 중단합니다.

노드는 fun 외부에 존재하는 DOM 객체를 저장합니다(항상 존재하며, 삭제되더라도 문서 트리에서만 제거됩니다). fun이 실행된 후 DOM 간의 순환 참조를 구성하는 클로저가 생성됩니다. 개체 및 콜백 함수( node-function-node)를 사용하면 IE 6에서 메모리 누수가 발생합니다.

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