[전단 면접] 역할 영역 과 폐쇄
변수 향상 에 대한 이 해 를 말씀 해 주세요.
this 의 몇 가지 다른 사용 장면 을 설명 합 니 다.
a 탭 10 개 를 만 들 고 클릭 할 때 해당 하 는 번 호 를 표시 합 니 다.
어떻게 작용 역 을 이해 합 니까
실제 개발 에서 폐쇄 적 인 응용
callapply bind 수 동 구현
2. 지식 포인트
2.1 상하 문 실행
범위: script 또는 함수
전역: 변수 정의, 함수 성명 script
함수: 변수 정의, 함수 성명, this, arguments (실행 전)
함수 성명 과 함수 표현 식 의 차이 점:
a(); // 。
var a = function(){}
b(); //
function b(){}
변 수 를 정의 할 때 그의 변 수 를 기본적으로 향상 시 킵 니 다. (그의 실행 컨 텍스트 에 만 한 정 됩 니 다. 예 를 들 어 script 과 함수 중)
console.log(a);
var a = 0;
사실은
var a;
console.log(a);
a = 0;
2.2 this
this 는 실행 할 때 만 확인 할 수 있 고 정의 할 때 확인 할 수 없습니다.
var a = {
name:'a',
fn:function(){
console.log(this.name);
}
}
a.fn(); // a
a.fn.apply({name:'b'}); // b a.fn.call({name:'b'});
var fn1 = a.fn();
fn1(); // undefined
this 의 사용 장면
구조 함수 중 (구조의 대상 을 가리 키 는)
function Fun(name){
this.name = name;
}
var f = new Fun('a');
console.log(f.name);
대상 속성 중 (대상 지향)
일반 함수 중 (window 지향)
call apply bind
함수 의 this 지향 을 바 꾸 는 데 사 용 됩 니 다. 용법 이 약간 다 릅 니 다.
call: 뒤의 매개 변 수 는 호출 함수 의 매개 변수 목록 입 니 다.
function greet(name) {
console.log(this.animal,name);
}
var obj = {
animal: 'cats'
};
greet.call(obj,' ');
apply: 두 번 째 매개 변 수 는 호출 함수 의 매개 변수 배열 입 니 다.
function greet(name) {
console.log(this.animal,name);
}
var obj = {
animal: 'cats'
};
greet.apply(obj,[' ']);
bid: 바 인 딩 함수 가 호출 될 때 bid 가 들 어 오 는 매개 변 수 는 목표 함수 의 매개 변수 목록 의 시작 위치 에 삽입 되 고 바 인 딩 함수 에 전 달 된 매개 변 수 는 그 뒤 를 따 를 것 입 니 다.
var fun = function (name1,name2){
console.log(this);
console.log(name);
}.bind({a:1},"name1");
fun("name2");
arguments 의 this:
var length = 10;
function fn(){
alert(this.length)
}
var obj = {
length: 5,
method: function(fn) {
arguments[0]()
}
}
obj. method (fn) / / 출력 1 여 기 는 5 를 출력 하지 않 았 고 10 을 출력 하지 않 았 으 며 오히려 1 을 출력 했 습 니 다. 재 미 있 습 니 다.여기 arguments 는 javascript 의 내 장 된 대상 (mdn: arguments - JavaScript 참조) 으로 클래스 배열 (배열 처럼 길 지만 배열 방법 이 부족 합 니 다. slice. call 로 변환 할 수 있 고 위의 링크 를 구체 적 으로 참조 할 수 있 습 니 다) 입 니 다. 함수 의 매개 변 수 를 저장 합 니 다.즉, 여기 서 arguments [0] 는 당신 method 함수 의 첫 번 째 매개 변 수 를 말 합 니 다: fn, 그래서 arguments [0] () 의 뜻 은 fn () 입 니 다.
그런데 왜 여기에 5 를 출력 하지 않 았 는 지 의문 이다.내 method 에 this 를 사용 하 는데 obj 를 가리 키 지 말 아야 합 니까? 적어도 10 을 출력 할 수 있 습 니 다. 이 1 은 어떻게 된 겁 니까?
실제로 이 1 은 arguments. length, 즉 이 함수 매개 변수의 개수 입 니 다.왜 여기 this 가 arguments 를 가리 키 지?자바 script 에서 배열 은 숫자 로 속성 명 을 만 드 는 방법 에 불과 하기 때 문 입 니 다. 즉, arguments [0] () 의 뜻 은 arguments. 0 () 의 뜻 과 차이 가 많 지 않 기 때 문 입 니 다.
arguments = {
0: fn, // functon() {alert(this.length)}
1: , //
2: , //
...,
length: 1 //
}
그래서 여기 alert 가 나 온 결 과 는 1 입 니 다.
5 를 출력 하려 면 어떻게 써 야 하나 요?직접 method: fn 이면 됩 니 다.
2.3 역할 영역
블록 급 역할 영역 없 음
if(true){
var name = "test"
}
console.log(name);
블록 에 변 수 를 설명 하지 마 십시오.
함수 급 역할 영역 만
2.4 역할 영역 체인
자유 변수 현재 역할 영역 에 정의 되 지 않 은 변 수 는 자유 변수 입 니 다.
자유 변 수 는 아버지 급 역할 영역 에서 찾 습 니 다.실행 이 아 닌 부모 역할 영역 을 정의 합 니 다.
var a = 100;
function f1(){
var b = 200;
function f2(){
var c = 300;
console.log(a); //
console.log(b); //
console.log(c);
}
f2();
};
f1();
2.5 폐쇄
한 함수 에 다른 함 수 를 끼 워 넣 고 이 함 수 를 return 한 다음 에 이 return 에서 나 온 함 수 를 변수 에 저장 하면 닫 힌 패 키 지 를 만 듭 니 다.
닫 힌 두 개의 사용 장면
1. 함 수 를 반환 값 으로 한다
function fun(){
var a = 0;
return function(){
console.log(a); // ,
}
}
var f1 = fun();
a = 1000;
f1();
2. 함 수 를 매개 변수 로 한다
function fun(){
var a = 0;
return function(){
console.log(a); // ,
}
}
function fun2(f2){
a = 10000
f2();
}
var f1 = fun();
fun2(f1);
구체 적 인 설명 은 고급. - 폐쇄 적 인 설명.
폐쇄 적 인 두 가지 역할:
다른 함수 내부 변 수 를 읽 을 수 있 는 함수
함수 내부 변 수 를 메모리 에 계속 저장 할 수 있 습 니 다.
실제 응용 필드 1:
패 킷 을 닫 으 면 전체 에 노출 되 기 를 원 하지 않 는 변 수 를 '개인 변수' 로 밀봉 할 수 있 습 니 다.
만약 곱셈 을 계산 하 는 함수 가 있다 면, mult 함 수 는 number 형식의 인 자 를 받 고 곱셈 결 과 를 되 돌려 줍 니 다.함수 성능 을 향상 시 키 기 위해 서 우 리 는 캐 시 체 제 를 추가 하여 이전에 계 산 된 결 과 를 캐 시 합 니 다. 다음 에 같은 매개 변 수 를 만나면 결 과 를 직접 되 돌려 줄 수 있 고 연산 에 참여 하지 않 아 도 됩 니 다.여기에 캐 시 결 과 를 저장 하 는 변 수 는 외부 에 노출 되 지 않 아 도 되 고 함수 실행 이 끝 난 후에 도 저장 되 어야 하기 때문에 패 키 지 를 닫 을 수 있 습 니 다.
상위 코드:
function calculate(param){
var cache = {};
return function(){
if(!cache.parame){
return cache.param;
}else{
// ....
//cache.param = result
//
}
}
}
실제 응용 장면 2
국부 변수의 수명 을 연장 하 다
img 대상 은 데이터 보고 에 자주 사 용 됩 니 다. 다음 과 같 습 니 다.
var report = function( src ){
var img = new Image();
img.src = src;
};
report( 'http://xxx.com/getUserInfo' );
그러나 배경 기록 을 조회 한 결과 일부 저 버 전 브 라 우 저의 실현 에 bug 가 존재 하기 때문에 이 브 라 우 저 에서 report 함 수 를 사용 하여 데 이 터 를 보고 하면 30% 정도 의 데 이 터 를 잃 어 버 린 다 는 것 을 알 수 있 습 니 다. 즉, report 함 수 는 매번 HTTP 요청 을 성공 적 으로 하 는 것 이 아 닙 니 다.
데 이 터 를 잃 어 버 린 이 유 는 img 이 report 함수 의 부분 변수 이기 때 문 입 니 다. report 함수 호출 이 끝 난 후에 img 부분 변 수 는 바로 소각 되 었 습 니 다. 이때 HTTP 요청 을 하지 못 했 을 수도 있 습 니 다. 그래서 이번 요청 은 잃 어 버 릴 것 입 니 다.
지금 우 리 는 img 변 수 를 폐쇄 로 닫 으 면 잃 어 버 린 문 제 를 해결 할 수 있 습 니 다.
var report = (function(){
var imgs = [];
return function( src ){
var img = new Image();
imgs.push( img );
img.src = src;
}
})();
폐쇄 단점: 자원 낭비!
3. 문제 풀이
3.1 변수 향상 에 대한 이 해 를 말 합 니 다.
변수 정의 와 함수 설명
함수 성명 과 함수 표현 식 의 차이 에 주의 하 십시오.
변 수 를 정의 할 때 그의 변 수 를 기본적으로 향상 시 킵 니 다. (그의 실행 컨 텍스트 에 만 한 정 됩 니 다. 예 를 들 어 script 과 함수 중)
console.log(a);
var a = 0;
사실은
var a;
console.log(a);
a = 0;
3.2 this 의 몇 가지 다른 사용 장면 설명
3.3 a 탭 10 개 를 만 들 고 클릭 할 때 해당 하 는 번 호 를 표시 합 니 다.
실현 방법 1: let 성명 i
var body = document.body;
console.log(body);
for (let i = 0; i < 10; i++) {
let obj = document.createElement('i');
obj.innerHTML = i + '
';
body.appendChild(obj);
obj.addEventListener('click',function(){
alert(i);
})
}
실현 방법 2 포장 역할 영역
var body = document.body;
console.log(body);
for (var i = 0; i < 10; i++) {
(function (i) {
var obj = document.createElement('i');
obj.innerHTML = i + '
';
body.appendChild(obj);
obj.addEventListener('click', function () {
alert(i);
})
})(i)
}
3.4 실제 개발 에서 폐쇄 적 인 응용
다른 함수 내부 변 수 를 읽 을 수 있 는 함수
함수 내부 변 수 를 메모리 에 계속 저장 할 수 있 습 니 다.
패키지 변수, 권한 수렴
응용
var report = (function(){
var imgs = [];
return function( src ){
var img = new Image();
imgs.push( img );
img.src = src;
}
})();
변수 소각 방지 에 사용 합 니 다.
응용
function isFirstLoad() {
var arr = [];
return function (str) {
if (arr.indexOf(str) >= 0) {
console.log(false);
} else {
arr.push(str);
console.log(true);
}
}
}
var fun = isFirstLoad();
fun(10);
fun(10);
arr 를 함수 내부 에 봉 하여 임의로 수정 하 는 것 을 금지 하고 변수 가 소각 되 는 것 을 방지 합 니 다.
3.5 수 동 으로 callapply bind 실현
Function.prototype.myCall = function (context) {
if (typeof this !== 'function') {
return undefined; // Function.prototype.myCall()
}
context = context || window;
const fn = Symbol();
context[fn] = this;
const args = [...arguments].slice(1);
const result = context[fn](...args);
delete context[fn];
return result;
}
apply 는 유사 한 call 을 실현 하고 매개 변 수 는 배열 입 니 다.
Function.prototype.myApply = function (context) {
if (typeof this !== 'function') {
return undefined; // Function.prototype.myCall()
}
context = context || window;
const fn = Symbol();
context[fn] = this;
let result;
if (arguments[1] instanceof Array) {
result = context[fn](...arguments[1]);
} else {
result = context[fn]();
}
delete context[fn];
return result;
}
1. 구조 함수 호출 여 부 를 판단 합 니 다.
2. 매개 변 수 는 목표 함수 의 시작 위치 에 삽입 해 야 합 니 다.
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
const _this = this
const args = [...arguments].slice(1)
return function F() {
//
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.