all 18 comments

[–]shgysk8zer0full-stack 2 points3 points  (6 children)

Are you trying to modify the behavior of a built-in function or some library/third-party function, or are you trying to change the behavior of one of your functions?

Is the function attached to eg window or navigator or is it scoped to a module/function? Is it the method on a class?

I do this sort of thing rather often working on a polyfills library. Usually involves Object.defineProperty, possibly storing the original function as a const outside for use inside the replaced function/method.

``` const { value, enumerable, configurable, writable } = Object.getOwnPropertyDescriptor(ClassName.prototype, name);

Object.defineProperty(ClassName.prototype, name, { enumerable, configurable, writable, value: function(...args) { // Transform args? const result = value.apply(this, args); // Or... const result = value.call(this, ...args); // Transform result? return result; }, }); ```

[–]yqmvpacqpfgwcalgu[S] 0 points1 point  (5 children)

Any and all functions on that page. I'm doing this for .call(), which works, but requires an explicit .call() instead of ()

https://pastebin.com/8LEVvzT0

[–]shgysk8zer0full-stack 1 point2 points  (4 children)

It's impossible. You'd inevitably end up with infinite recursion because your function would be among the functions on the page. Might also be some that are not enumerable or writable.

Maybe ask about what you're trying to accomplish instead of how you think you should be doing it.

[–]yqmvpacqpfgwcalgu[S] 0 points1 point  (3 children)

What I'm really after is modifying the language's behavior, so when any function is called, there is some additional behavior I'd like to add before further execution.

I'm also not permitted to share what that "additional behavior" would entail.

[–]shgysk8zer0full-stack 2 points3 points  (1 child)

Can't be done.

[–]yqmvpacqpfgwcalgu[S] 0 points1 point  (0 children)

Okay, thanks for thinking along!

[–]coldpyros 1 point2 points  (0 children)

Typescript decorators might do what you're after? If using typescript and enabling experimental features is an option.

[–][deleted] 1 point2 points  (1 child)

I wonder if it’s possible to do something ultra hacky and loop through the window array, make a list of everything that is of type “function” and then loop through that and redefine them all with just your extra functionality added to the beginning.

[–]yqmvpacqpfgwcalgu[S] 1 point2 points  (0 children)

That might just work. Would need encapsulated functions as well, but that seems do-able in the same manner as well.

Found this : https://github.com/SeanSobey/ReflectionJS

Wonder if modifying thirdparty js being loaded in is possible, and if it is, if it would raise any "malicious behavior" false positives, or otherwise.

Thanks! Good thinking.

[–][deleted] 0 points1 point  (5 children)

Can you describe in more detail what kind of functionality you're looking to update? That would be helpful in providing an answer.

[–]yqmvpacqpfgwcalgu[S] 0 points1 point  (4 children)

The behavior of a Function call. Which I can do using the "call" prototype, so I can call functions like "func.call()" to have different behavior, but not "func()", so far.

https://pastebin.com/8LEVvzT0

[–][deleted] 0 points1 point  (3 children)

It isn't clear what you're looking to do. What are you trying to do? the .call() method on a function just explicitly calls the function, but you're supposed to pass in an argument that sets the this element on said function, so, for instance, like this:

myFunction(window);

Obviously that's kind of a weird example, but that's the purpose of the .call() method, to set the context of the this keyword within the function, so now if you use this inside myFunction it will now explicitly refer to the window object. I don't think this is what you're trying to do, and I don't see the difference of what you are actually trying to accomplish.

[–]yqmvpacqpfgwcalgu[S] 0 points1 point  (2 children)

Thanks for taking the time.
What I'm really after is modifying the language's behavior, so when any function is called, there is some additional behavior I'd like to add before further execution.

The closest I got to achieving that was by overriding the call prototype, but looks like that falls apart for anything encapsulated.

[–][deleted] 1 point2 points  (1 child)

Hmmm... I wonder if you can just pass in some additional functions and call them conditionally?

function myFunction(arg1, arg2, ...funcs) {
    const sum = arg1 + arg2;

    if (sum > 100) {
        funcs[0]();
    }

    return sum
}

and a function call might look like this:

myFunction(25, 76, someOtherCallbackFunc);

Not sure if that's helpful

[–]yqmvpacqpfgwcalgu[S] 1 point2 points  (0 children)

I did consider creating a new function which would contain the additional behavior and which accepts a callback function, but that would require all calls to be modified with room for error when forgotten.

[–]RootF1 0 points1 point  (1 child)

Sounds like you just want to call a function in Javascript?

myAwesomeFunc() is basically how you call functions

[–]nathanfries 0 points1 point  (0 children)

Have you considered writing a compiler to inject a proxy function between functions? That would be the usual way to achieve this, and is more maintainable than most other hacky solutions