자바 스크립트 함수를 선언 한 후 변경할 수 있습니까?
내가 가지고 있다고 가정 해 봅시다 var a = function() { return 1; }
. 반환 하도록 변경할 a
수 있습니까? 모든 기능이 객체이기 때문에 아마도 객체 의 속성을 편집하여 ?a()
2
a
업데이트 : 와, 모든 응답에 감사드립니다. 그러나 단순히 변수를 재 할당하는 것이 아니라 실제로 기존 함수를 편집하려는 것이 두렵습니다. Scala에서 부분 함수 를 결합 하여 새로운 PartialFunction
. Javascript로 비슷한 것을 작성하는 데 관심이 있으며 완전히 새로운 Function
객체를 만드는 대신 기존 함수를 업데이트 할 수 있다고 생각했습니다 .
다음과 같이 선언에 액세스 할 수없는 기존 함수를 수정했습니다.
// declare function foo
var foo = function (a) { alert(a); };
// modify function foo
foo = new Function (
"a",
foo.toSource()
.replace("alert(a)", "alert('function modified - ' + a)")
.replace(/^function[^{]+{/i,"") // remove everything up to and including the first curly bracket
.replace(/}[^}]*$/i, "") // remove last curly bracket and everything after<br>
);
toSource () 대신 toString () 을 사용 하여 함수의 선언이 포함 된 문자열을 가져올 수 있습니다. 함수 생성자와 함께 사용할 문자열을 준비하고 함수의 소스를 수정하기 위해 replace ()에 대한 일부 호출.
함수 재정의를 포함하여 자바 스크립트로 모든 종류의 재미있는 작업을 수행 할 수 있습니다.
var a = function(){ return 1; }
alert(a()); //1
// keep a reference
var old = a;
// redefine
a = function(){
// call the original function with any arguments specified, storing the result
var originalResult = old.apply(old, arguments);
// add one
return originalResult + 1;
};
alert(a()); //2
짜잔.
편집 : 더 미친 시나리오에서이를 표시하도록 업데이트되었습니다.
var test = new String("123");
console.log(test.toString()); // logs 123
console.log(test.substring(0)); // logs 123
String.prototype.substring = function(){ return "hahanope"; }
console.log(test.substring(0)); // logs hahanope
여기서 "test"가 먼저 정의되고 나중에 substring ()을 재정의하더라도 변경 사항이 여전히 적용되는 것을 볼 수 있습니다.
참고 :이 작업을 수행하는 경우 아키텍처를 정말로 재고해야합니다 ... 5 년 후의 가난한 개발자가 1을 반환해야하는 함수 정의를보고있을 때 혼란 스러울 것입니다. ,하지만 항상 2를 반환하는 것 같습니다 ....
var a = function() { return 1; }
alert(a()) // 1
a = function() { return 2; }
alert(a()) // 2
기술적으로는 하나의 함수 정의를 잃고 다른 정의로 대체합니다.
따라서 기존 변수에 다른 함수를 재 할당하는 것이 아니라 함수의 코드를 제자리에서 직접 수정하려고합니다.
나는 그것을 말하는 것이 싫지만, 내가 그것을 알아낼 수 있고 시도해 보았지만, 그것은 할 수 없습니다. 사실, 함수는 객체이며, 따라서 객체 자체에서 조정하고 덮어 쓸 수있는 메서드와 속성이 있습니다. 불행히도 함수 본문은 그중 하나가 아닙니다. 공용 자산에 할당되지 않습니다.
MDN에 대한 문서 에는 함수 개체의 속성과 메서드가 나열되어 있습니다. 그들 중 어느 것도 우리에게 외부에서 기능 본체를 조작 할 기회를주지 않습니다.
이는 spec 에 따라 함수 본문이 [[Code]]
함수 객체 의 내부 속성에 저장되어 직접 액세스 할 수 없기 때문입니다.
함수를 재정의 할 필요없이 이것은 어떨까요?
var a = function() { return arguments.callee.value || 1; };
alert(a()); // => 1
a.value = 2;
alert(a()); // => 2
나는 전역 변수 "old"를 좋아하지 않는 jvenema의 솔루션을 고수하고 있습니다. 새 기능 내부에 이전 기능을 유지하는 것이 좋습니다.
function a() { return 1; }
// redefine
a = (function(){
var _a = a;
return function() {
// You may reuse the original function ...
// Typical case: Conditionally use old/new behaviour
var originalResult = _a.apply(this, arguments);
// ... and modify the logic in any way
return originalResult + 1;
}
})();
a() // --> gives 2
모든 실행 가능한 솔루션은 "함수 래핑 접근 방식"을 고수합니다. 그들 중 가장 신뢰할 수있는 것은 rplantiko 중 하나 인 것 같습니다 .
이러한 함수 래핑은 쉽게 추상화 할 수 있습니다. 개념 / 패턴 자체를 "메소드 수정"이라고 할 수 있습니다. 그 구현은 확실히 Function.prototype
. 그것은 좋은 같은 표준 프로토 타입 방법을 수정하여 일일 백업하는 것 before
, after
, around
, afterThrowing
와 afterFinally
.
rplantiko의 앞서 언급 한 예는 ...
function a () { return 1; }
// redefine
a = (function () {
var _a = a;
return function () {
// You may reuse the original function ...
// Typical case: Conditionally use old/new behaviour
var originalResult = _a.apply(this, arguments);
// ... and modify the logic in any way
return originalResult + 1;
};
})();
a(); // --> gives 2
... 그리고를 사용 [around]
하면 코드는 ...
function a () { return 1; }
console.log("a : ", a);
console.log("a() : ", a());
a = a.around(function (proceed, interceptor, args) {
return (proceed() + 1);
});
console.log("a : ", a);
console.log("a() : ", a());
나중에 다시 정의 할 수 없습니까? 변경을 원할 때 다음과 같이 재정의하십시오.
a = function() { return 2; }
자바 스크립트를 디버깅 중이고 코드 변경이 페이지에 미치는 영향을 확인하려면이 Firefox 확장을 사용하여 자바 스크립트를 보거나 변경할 수 있습니다.
JS firefox 확장 실행 : https://addons.mozilla.org/en-US/firefox/addon/1729
This is a Clear Example based on a control timepicker eworld.ui
www.eworldui.net
Having a TimePicker eworld.ui
where JavaScript is unreachable from outside, you can't find any js related to those controls. So how can you add a onchange event to the timepicker ?
There is a js
function called when you Select
a time between all the options that the control offer you. This function is: TimePicker_Up_SelectTime
First you have to copy the code inside this function.
Evaluate...quikwatch...TimePicker_Up_SelectTime.toString()
function TimePicker_Up_SelectTime(tbName, lblName, divName, selTime, enableHide, postbackFunc, customFunc) {
document.getElementById(tbName).value = selTime;
if(lblName != '')
document.getElementById(lblName).innerHTML = selTime;
document.getElementById(divName).style.visibility = 'hidden';
if(enableHide)
TimePicker_Up_ShowHideDDL('visible');
if(customFunc != "")
eval(customFunc + "('" + selTime + "', '" + tbName + "');");
eval(postbackFunc + "();");
}
Now
Using the code that you have saved before reassign the same source code but add whatever you want..
TimePicker_Up_SelectTime = function (tbName, lblName, divName, selTime, enableHide, postbackFunc, customFunc) { document.getElementById(tbName).value = selTime; if (lblName != '') document.getElementById(lblName).innerHTML = selTime; document.getElementById(divName).style.visibility = 'hidden'; if (enableHide) TimePicker_Up_ShowHideDDL('visible'); if (customFunc != "") eval(customFunc + "('" + selTime + "', '" + tbName + "');"); eval(postbackFunc + "();");
>>>>>>> My function >>>>> RaiseChange(tbName);
}
I've added My Function to the function so now I can simulate an onchange event when I select a time.
RaiseChange(...) could be whatever you want.
You can change functions like other objects
var a1 = function(){return 1;}
var b1 = a1;
a1 = function(){
return b1() + 1;
};
console.log(a1()); // return 2
// OR:
function a2(){return 1;}
var b2 = a2;
a2 = function(){
return b2() + 1;
};
console.log(a2()); // return 2
Absolutely. Just assign to it a new function.
function get_func(func) {//from StackOverflow
//var args = Array.prototype.slice.call(arguments);
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var args = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
//var code = func.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1];
var code =fnStr.slice(fnStr.indexOf("{") + 1, fnStr.lastIndexOf("}"));
var func_full_name=fnStr.substr(0, fnStr.indexOf('{') );
var func_name=fnStr.slice(9, fnStr.indexOf('('));
if(args === null){ args = []; }
return { func_name:func_name,func_full_name:func_full_name, code:code, args:args};
}
function str_trim(str){
//replaces multi-line characters
return str.replace(/\n/g,'').replace(/^ +| +$/gm, '').trim();
}
function edit_func(func,callback){
var a_func=get_func(func);
var lines = a_func.code.split('\n');
var output=[];
for(var i=0;i<lines.length;i++){
var code=str_trim(lines[i]);
if(code!=''){
code =callback(code,output.length,a_func.args);
output.push(code);
}
}
//var test=Function(['a','b'],'alert(a);alert(b);');
//test(1,2);
//func=Function(a_func.args,output.join('\n'));
//return func;
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.text =a_func.func_full_name+'{'+ output.join('\n') + '}' ;
head.appendChild(script);
}
function test(id) {
var x, y;
x = 5;
y = 10;
alert(x + y);
alert(id);
}
edit_func(test,function(code,line,args){
if(line==3){
return 'alert(x*y);';
}
return code;
});
test(3);
Try this one It will change the original function with a new code using a callback for inspecting every line of code.
참고URL : https://stackoverflow.com/questions/2136522/can-you-alter-a-javascript-function-after-declaring-it
'Programing' 카테고리의 다른 글
Visual Studio 2015에서 게시-신뢰할 수없는 인증서 허용 (0) | 2020.12.07 |
---|---|
Windows 배치 스크립트에서 파일 크기를 어떻게 확인할 수 있습니까? (0) | 2020.12.07 |
오류 :“입력이 올바른 UTF-8이 아닙니다. 인코딩을 나타냅니다!” (0) | 2020.12.07 |
C 구조체에서 멤버 숨기기 (0) | 2020.12.07 |
내 열거 형은 클래스 또는 네임 스페이스가 아닙니다. (0) | 2020.12.07 |