클로즈업 사유 변수

5868 단어 HTML5CSSJavaScript
다음으로 이동:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */

 
순환 중 클립 만들기: 흔히 볼 수 있는 오류 섹션
ECMAScript 2015let 키워드를 도입하기 전에 순환에서 흔히 볼 수 있는 클립 생성 문제가 있습니다.다음 예제를 참조하십시오.

Helpful notes will appear here

E-mail:

Name:

Age:

function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
}

setupHelp();

 
배열helpText에는 해당 문서의 IDinput에 연관된 세 가지 유용한 프롬프트가 정의되어 있습니다.이 세 가지 정의를 순환하여 상응하는 input 이벤트 처리 함수를 추가하여 도움말을 표시합니다.
이 코드를 실행하면 원하는 효과에 도달하지 못한 것을 발견할 수 있습니다.어느 것onfocus에 초점을 맞추든지 나이에 대한 정보가 나온다.
할당input이 클로즈업이었기 때문이다.이 클립들은 그들의 함수 정의와 onfocus 작용역에서 포획된 환경으로 구성되어 있다.이 세 개의 클립은 순환에서 생성되지만, 그들은 같은 어법 작용역을 공유하고, 이 작용역에 변수item이 존재한다.onfocus의 리셋이 실행될 때 setupHelp 의 값이 결정됩니다.순환은 이벤트가 터치되기 전에 이미 실행되었기 때문에 변수 대상item.help(세 개의 클립에 의해 공유됨)은 item의 마지막 항목을 가리켰다.
이 문제를 해결하는 방안 중 하나는 더 많은 클립을 사용하는 것이다. 특히 앞에서 말한 함수 공장을 사용한다.
function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function makeHelpCallback(help) {
  return function() {
    showHelp(help);
  };
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
  }
}

setupHelp();

 
이 코드는 우리가 기대한 대로 작동할 수 있다.모든 리셋은 같은 환경을 공유하지 않습니다. helpText 함수는 모든 리셋에 새로운 어법 환경을 만듭니다.이러한 환경에서 makeHelpCallbackhelp 수조에 대응하는 문자열을 가리킨다.
다른 방법은 익명 클립을 사용했다.
function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    (function() {
       var item = helpText[i];
       document.getElementById(item.id).onfocus = function() {
         showHelp(item.help);
       }
    })(); //          item          
  }
}

setupHelp();

지나치게 많은 클립을 피하고let 키워드를 사용할 수 있습니다.
function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    let item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
}

setupHelp();

이 예는 helpText 대신 let 을 사용하기 때문에 모든 클립은 블록 작용역의 변수를 연결합니다. 이것은 더 이상 추가 클립이 필요하지 않다는 것을 의미합니다.
성능 고려 사항
특정 작업이 클립을 사용하지 않으면 다른 함수에서 함수를 만드는 것은 현명하지 않다. 클립은 처리 속도와 메모리 소모에 있어 스크립트 성능에 부정적인 영향을 미치기 때문이다.
예를 들어 새로운 대상이나 클래스를 만들 때 방법은 대상의 원형에 연결되어야 하며, 대상의 구조기에 정의되지 않아야 한다.왜냐하면 이것은 매번 구조기가 호출될 때마다 방법이 다시 한 번 부여될 것이다. (즉, 모든 대상의 창설)
다음 예를 고려하십시오.
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

위의 코드에서 우리는 클립의 장점을 이용하지 않았기 때문에 클립을 사용하는 것을 피할 수 있다.다음과 같이 수정되었습니다.
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype = {
  getName: function() {
    return this.name;
  },
  getMessage: function() {
    return this.message;
  }
};

그러나 우리는 원형을 새롭게 정의하는 것을 건의하지 않는다.다음과 같이 변경할 수 있습니다.
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

앞의 두 예에서 상속된 원형은 모든 대상을 공유할 수 있으며, 매번 대상을 만들 때 방법을 정의할 필요가 없다.대상 모델의 세부 1장을 참고하면 더욱 상세한 정보를 얻을 수 있다.

좋은 웹페이지 즐겨찾기