jslint 오류 '루프 내에서 함수를 만들지 마십시오'를 수정하는 방법?
나는 우리의 모든 JS 코드가 jslint를 통과하도록 노력하고 있으며, 때로는 나중에 적절하게 수정하려는 의도로 레거시 코드를 전달하는 옵션을 많이 조정하기도합니다.
jslint가 해결 방법이 없다고 불평하는 한 가지가 있습니다. 즉, 이와 같은 구조를 사용할 때 '루프 내에서 함수를 만들지 마십시오'라는 오류가 발생합니다.
for (prop in newObject) {
// Check if we're overwriting an existing function
if (typeof newObject[prop] === "function" && typeof _super[prop] === "function" &&
fnTest.test(newObject[prop])) {
prototype[prop] = (function(name, func) {
return function() {
var result, old_super;
old_super = this._super;
this._super = _super[name];
result = func.apply(this, arguments);
this._super = old_super;
return result;
};
})(prop, newObject[prop]);
}
}
이 루프는 기존 클래스를 확장하는 클래스가 확장 클래스의 멤버를 호출 할 때 확장 클래스의 수퍼 속성을 유지하는 클래식 상속의 JS 구현의 일부입니다. 명확히하기 위해 위의 구현은 John Resig 의이 블로그 게시물에서 영감을 얻었습니다 .
하지만 루프 내에 생성 된 다른 함수 인스턴스도 있습니다.
지금까지 유일한 해결 방법은 jslint에서 이러한 JS 파일을 제외하는 것이지만, 지속적인 통합 및 빌드 워크 플로의 일부로 코드 유효성 검사 및 구문 검사에 jslint를 사용하려고합니다.
이와 같은 기능을 구현하는 더 좋은 방법이 있습니까? 아니면 jslint를 통해 이와 같은 코드를 조정할 수있는 방법이 있습니까?
Douglas Crockford는 위의 것을 달성하는 새로운 관용적 방법을 가지고 있습니다. 그의 이전 기술은 내부 함수를 사용하여 변수를 바인딩하는 것이었지만 새로운 기술은 함수 메이커를 사용합니다. 그의 "궁극적 인 기능"강연 슬라이드의 74 번 슬라이드를 참조하십시오 . [이 슬라이드 공유는 더 이상 존재하지 않습니다.]
게으른 사람들을 위해 다음은 코드입니다.
function make_handler(div_id) {
return function () {
alert(div_id);
};
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = make_handler(div_id);
}
(저는이 질문이 게시 된 지 수개월 후에 우연히 발견했습니다 ...)
루프에서 함수를 만들면 루프가 반복 될 때마다 함수 인스턴스가 생성됩니다. 생성되는 함수가 실제로 각 반복마다 다르지 않는 한, 함수 생성기를 루프 외부에 두는 방법을 사용하십시오. 이렇게하면 Crockery가 아니라 코드를 읽는 다른 사람들이 이것이 당신의 의도임을 알 수 있습니다. .
함수가 실제로 반복 (또는 반복에서 생성 된 객체)의 다른 값에 할당되는 동일한 함수 인 경우 대신 함수를 명명 된 변수에 할당하고 함수의 단일 인스턴스를 고리:
handler = function (div_id) {
return function() { alert(div_id); }
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = handler(div_id);
}
Greater commentary/discussion about this was made by others smarter than me when I posed a similar question here on Stack Overflow: JSlint error 'Don't make functions within a loop.' leads to question about Javascript itself
As for JSLint: Yes, it is dogmatic and idiomatic. That said, it is usually "right" -- I discover that many many people who vocalize negatively about JSLint actually don't understand (the subtleties of) Javascript, which are many and obtuse.
Literally, get around the problem by doing the following:
- Create a
.jshintrc
file Add the following line to your
.jshintrc
file{"loopfunc" : true, // tolerate functions being defined in loops }
JSLint is only a guide, you don't always have to adhere to the rules. The thing is, you're not creating functions in a loop in the sense that it's referring to. You only create your classes once in your application, not over and over again.
If you are using JQuery, you might want to do something like this in a loop:
for (var i = 0; i < 100; i++) {
$("#button").click(function() {
alert(i);
});
}
To satisfy JSLint, one way to work around this is (in JQuery 1.4.3+) to use the additional handler data argument to .click()
:
function new_function(e) {
var data = e.data; // from handler
alert(data); // do whatever
}
for (var i = 0; i < 100; i++) {
$("#button").click(i, new_function);
}
Just move your:
(function (name, func) {...})()
block out of the loop and assign it to a variable, like:
var makeFn = function(name, func){...};
Then in the loop have:
prototype[prop] = makeFn(...)
'IT Share you' 카테고리의 다른 글
Control.Applicative를 사용하여 더 깨끗한 Haskell을 작성하는 방법은 무엇입니까? (0) | 2020.12.04 |
---|---|
.svn / text-base / file.svn-base를 열 수 없습니까? (0) | 2020.12.04 |
Excel에서 특정 워크 시트를 활성화하는 방법은 무엇입니까? (0) | 2020.12.04 |
iPhone 부드러운 스케치 그리기 알고리즘 (0) | 2020.12.04 |
함수 반환 유형 및 인수 유형을 아는 방법? (0) | 2020.12.04 |