원본을 참조하면서 JavaScript 함수 재정의
a()
재정의하려는 함수가 있지만 a()
컨텍스트에 따라 순서대로 원본 을 수행 해야합니다 . 예를 들어, 때때로 페이지를 생성 할 때 다음과 같이 재정의하고 싶습니다.
function a() {
new_code();
original_a();
}
때로는 이렇게 :
function a() {
original_a();
other_new_code();
}
original_a()
오버 라이딩 내에서 어떻게 얻을 수 a()
있습니까? 가능합니까?
이런 식으로 오버 라이딩에 대한 대안을 제안하지 마십시오. 나는이 방법에 대해 구체적으로 묻고 있습니다.
다음과 같이 할 수 있습니다.
var a = (function() {
var original_a = a;
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})();
original_a
익명 함수 내부에 선언 하면 전역 네임 스페이스가 복잡해지지 않지만 내부 함수에서 사용할 수 있습니다.
의견에 언급 된 Nerdmaster와 마찬가지로 끝에를 포함해야합니다 ()
. 외부 함수를 호출 하지 말고 외부 함수를 호출하고 결과 (두 내부 함수 중 하나)를에 저장하려고합니다 .a
a
프록시 패턴은 당신을 도울 수 있습니다
(function() {
// log all calls to setArray
var proxied = jQuery.fn.setArray;
jQuery.fn.setArray = function() {
console.log( this, arguments );
return proxied.apply( this, arguments );
};
})();
위의 코드는 "proxied"변수를 숨기는 함수로 코드를 래핑합니다. jQuery의 setArray-method를 클로저에 저장하고 덮어 씁니다. 그런 다음 프록시는 모든 호출을 메소드에 기록하고 호출을 원본에 위임합니다. apply (this, arguments)를 사용하면 호출자가 원래 메소드와 프록시 메소드의 차이점을 알 수 없습니다.
고마워 프록시 패턴이 실제로 도움이되었습니다 .... ... 실제로 전역 함수 foo를 호출하고 싶었습니다 .. 특정 페이지에서 몇 가지 확인을해야합니다. 그래서 나는 다음을 수행했다.
//Saving the original func
var org_foo = window.foo;
//Assigning proxy fucnc
window.foo = function(args){
//Performing checks
if(checkCondition(args)){
//Calling original funcs
org_foo(args);
}
};
Thnx 이것은 정말 나를 도와
다음과 같은 구문을 사용하여 함수를 재정의 할 수 있습니다.
function override(f, g) {
return function() {
return g(f);
};
}
예를 들면 다음과 같습니다.
a = override(a, function(original_a) {
if (condition) { new_code(); original_a(); }
else { original_a(); other_new_code(); }
});
편집 : 오타가 수정되었습니다.
임의의 인수 전달 :
a = override(a, function(original_a) {
if (condition) { new_code(); original_a.apply(this, arguments) ; }
else { original_a.apply(this, arguments); other_new_code(); }
});
위의 예제 는 함수 재정의에 올바르게 적용 this
되거나 arguments
올바르게 전달 되지 않습니다 . 밑줄 _.wrap ()은 기존 함수를 래핑 this
하고 arguments
올바르게 적용 하고 전달 합니다. 참조 : http://underscorejs.org/#wrap
The answer that @Matthew Crumley provides is making use of the immediately invoked function expressions, to close the older 'a' function into the execution context of the returned function. I think this was the best answer, but personally, I would prefer passing the function 'a' as an argument to IIFE. I think it is more understandable.
var a = (function(original_a) {
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})(a);
I had some code written by someone else and wanted to add a line to a function which i could not find in the code. So as a workaround I wanted to override it.
None of the solutions worked for me though.
Here is what worked in my case:
if (typeof originalFunction === "undefined") {
originalFunction = targetFunction;
targetFunction = function(x, y) {
//Your code
originalFunction(a, b);
//Your Code
};
}
I've created a small helper for a similar scenario because I often needed to override functions from several libraries. This helper accepts a "namespace" (the function container), the function name, and the overriding function. It will replace the original function in the referred namespace with the new one.
The new function accepts the original function as the first argument, and the original functions arguments as the rest. It will preserve the context everytime. It supports void and non-void functions as well.
function overrideFunction(namespace, baseFuncName, func) {
var originalFn = namespace[baseFuncName];
namespace[baseFuncName] = function () {
return func.apply(this, [originalFn.bind(this)].concat(Array.prototype.slice.call(arguments, 0)));
};
}
Usage for example with Bootstrap:
overrideFunction($.fn.popover.Constructor.prototype, 'leave', function(baseFn, obj) {
// ... do stuff before base call
baseFn(obj);
// ... do stuff after base call
});
I didn't create any performance tests though. It can possibly add some unwanted overhead which can or cannot be a big deal, depending on scenarios.
In my opinion the top answers are not readable/maintainable, and the other answers do not properly bind context. Here's a readable solution using ES6 syntax to solve both these problems.
const orginial = someObject.foo;
someObject.foo = function() {
if (condition) orginial.bind(this)(...arguments);
};
So my answer ended up being a solution that allows me to use the _this variable pointing to the original object. I create a new instance of a "Square" however I hated the way the "Square" generated it's size. I thought it should follow my specific needs. However in order to do so I needed the square to have an updated "GetSize" function with the internals of that function calling other functions already existing in the square such as this.height, this.GetVolume(). But in order to do so I needed to do this without any crazy hacks. So here is my solution.
Some other Object initializer or helper function.
this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(
this.viewerContainer)
var viewer = this.viewer;
viewer.updateToolbarButtons = this.updateToolbarButtons(viewer);
Function in the other object.
updateToolbarButtons = function(viewer) {
var _viewer = viewer;
return function(width, height){
blah blah black sheep I can refer to this.anything();
}
};
'Programing' 카테고리의 다른 글
힙 대 이진 검색 트리 (BST) (0) | 2020.06.07 |
---|---|
Fragment와 FragmentActivity의 차이점은 무엇입니까? (0) | 2020.06.07 |
캡처 한 그룹 만 바꾸는 방법? (0) | 2020.06.07 |
슬래시를 이스케이프 처리하는 json_encode () (0) | 2020.06.07 |
루비에서 안전한 정수 파싱 (0) | 2020.06.07 |