Adjusting the size of wrapper functions

One common issue I encounter is the need to wrap a function on an object for various reasons. Is there a sophisticated method to maintain the original function's length property on the wrapper function?

For instance:

var x = {
    a: function(arg1, arg2) { /* do something */ }
};

function wrap(obj) {
    var original = obj.a;
    obj.a = function wrapper() {
        console.log('a called');
        original.apply(this, arguments);
    };
}

x.a.length; // => 2
wrap(x);
x.a.length; // => 0

What I aim to achieve:

var x = {
    a: function(arg1, arg2) { /* do something */ }
};

function wrap(obj) {
    var original = obj.a;
    obj.a = function wrapper() {
        console.log('a called');
        original.apply(this, arguments);
    };
    obj.a.length = original.length;
}

x.a.length; // => 2
wrap(x);
x.a.length; // => 2 (still actually 0)

However, this approach fails due to the non-writable nature of the length property.

Currently, my only solutions involve either (1) creating the function dynamically as a string and using eval/new Function, or (2) maintaining a large array of proxy functions with different lengths and selecting the appropriate one. These options don't seem elegant to me, and it should be reasonable to create a function with any length without explicitly specifying each argument within the function.

It appears that bind can internally handle this scenario:

function a(b, c) { }
a.bind(null).length; // => 2

This generates a wrapper function with the original length! This functionality is precisely what I would like to replicate myself.

Are there any other methods to achieve this goal?

Answer №1

The simplicity of the eval(...) method is what I appreciate the most.

function wrap(obj) {
    var f = obj.fun.toString();
    f = f.replace("{", "{ alert('wrapper'); ");
    obj.fun = eval('['+f+']')[0];
}

To take it to the next level, you could add a second parameter to the wrap function for the wrapper function and enhance the string manipulation operations for a more sophisticated approach.

If your aim is transparency in wrapping functions, leverage the dynamic capabilities of the programming language.


If you're open to extra processing in your JavaScript files, integrating hot patching or wrapping functionalities directly can be beneficial.

var x = {
    a: function(arg1, arg2) {
        (x._a || (function(){}))();
        ...perform actual function actions...
    }
}
function wrap(obj) {
    obj._a = function() {
        console.log("ok");
    }
}

Answer №2

If you find yourself needing to determine the length of functions, whether wrapped or unwrapped, without relying on the length property, consider using a method like the following:

Function.prototype.customLength = function() {
    return this.customLength || this.length;
};

var y = {
    c: function(item1, item2) { /* perform action */ },
    d: function(item1, item2, item3) { /* perform another action */ }
};

function wrapperFunc(object) {
    var originalFunc = object.c;
    object.c = function() {
        console.log('Function c has been called');
        originalFunc.apply(this, arguments);
    };
    object.c.customLength = originalFunc.length;
}

console.log(y.c.length); // => 2
wrapperFunc(y);
console.log(y.c.length); // => 0
console.log(y.c.customLength()); // => 2
console.log(y.d.customLength()); // => 3

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Chrome freezing after long use of React app

Seeking help with troubleshooting a general problem in a JavaScript app I developed using React. The app receives streaming data from a websocket at a high frequency and updates the user display accordingly. However, after running for more than 12 hours, n ...

Extracting a variable established on the client side and passing it to a server-side node backend

I am currently working on creating a comments section for a web application. The front end of the app displays information about the threading level of each comment. When users submit comments, I need to pass this threading information to the back end in o ...

Guide on how to reload the page with its initial URL after the URL has been modified using history.pushState()

After utilizing history.pushState(), I encountered an issue where the page would refresh with the current URL instead of the original one when the user refreshed the page. I attempted to detect a page refresh using methods such as cookies and hidden field ...

Unable to retrieve variable using the require statement

When attempting to access the variable 'app' from the required index.js in my test, I encounter difficulty resolving the 'app' variable. server.js 'use strict'; var supertestKoa = require('supertest-koa-agent'); ...

Ensure selected language is maintained when refreshing or changing view by utilizing switch i18n functionality

Hello there, I am facing a challenge with "JavaScript Localization" on my website. The issue is that I cannot figure out how to prevent the DOM from prioritizing the local language of the browser and instead use the language set in the switch as a referenc ...

Is it not possible to use array splice with a string that is in array format (i.e., split string

Why doesn't array splice work with a string that has been formatted into an array using the split() method? function _formatText(text) { var textList = text.replace(/\s+/g, ",").split(","); return textList.splice(1, 0, "<br />").join ...

Running a bash command within a Node.js application while having root privileges

There is a slight issue that I'm encountering. I have a nodejs app that needs to execute a command in the OS's bash with root privileges, for example: The command is: echo "$password" | /usr/bin/sudo /usr/bin/abc --key "$username" Below is my c ...

Understanding how to access POST content in Meteor.js is an important aspect

In my Meteor app, I am trying to retrieve data using POST requests. Here is the code snippet I am using on the server side: __meteor_bootstrap__.app.stack.splice (0, 0, { route: '/input', handle: function(req, res, next) { req.on(' ...

How can you display a specific word instead of the values 'true' or 'false' retrieved from an API in a FlatList component?

I need help figuring out how to render different text based on whether the value fetched from an API is 'true' or 'false'. For example, I want to display 'Hello' if the value is 'true' and 'Good Night' if i ...

No results found for the regex pattern

In the code below, I have implemented a regular expression to detect URLs in a string and convert them into hyperlinks: <body> <button onclick="myFunction()">Try it</button> <p id="demo"></p> <script> function myFunct ...

storing prepopulated form fields in vue

As I work on a complex form, my goal is to ensure that users do not lose their data when reloading the browser. Thankfully, modern browsers automatically refill data on reloads - even inputs with v-model retain their values during beforeMount. However, t ...

Challenge in backward compatibility when converting from .on() to .live()

Struggling to make hammer.js work with an outdated 1.6 jQuery in my CMS. The function "on()" isn't available, so I have to use "live()". Here are the two instances: 1. var hammertime = new Hammer(element[0], { drag_lock_to_axis: true }); hammertime. ...

Using Selenium and Python to showcase the source of an image within an iframe

My goal is to automatically download an image from shapeNet using Python and selenium. I have made progress, but I am stuck on the final step. from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.s ...

Exploring Angular.js: Finding the correct path in a JSON array

Within my Angular application, I have a $scope variable defined as follows. $scope.roleList2 = [ { "roleName" : "User", "roleId" : "role1", "children" : [ { "roleName" : "subUser1", "roleId" : "role11", "collapsed" : true, "children" : [ ...

In C#, you should assign the returned value from JavaScript to an array

I am in need of assistance with a javascript function that returns an array. My main queries are: (a) How can I call the Javascript function during OnInit or Onload? (b) The javascript function outputs an array, and I would like to store it within an ar ...

Pass a link by pressing Enter

Although the title may seem odd, I'll explain what I'm attempting to accomplish. I have a login form with two input fields, a checkbox, and a submit button. You can view a screenshot of it here: https://i.sstatic.net/nE1FY.png The terms of use a ...

Using values from a preexisting array to generate new arrays in JavaScript

I'm currently facing a challenge in JavaScript where I need to generate arrays based on the values of another array. For instance, I have an array of dates in string format (dates) listed below: ["30/09/2015", "31/10/2015", "30/11/2015", "31/12/2015 ...

Extract JSON data from Python API

Currently, I am delving into web programming and have created a Python API that queries an SQL database to return a JSON. The functionality of the API is as expected. In parallel, I've developed a controller where I execute a GET request to utilize t ...

javascript string assignment

Is it possible to conditionally assign a string based on the result of a certain condition, but for some reason, it's not working? var message = ""; if (true) { message += "true"; } else { message += "false" } console.log(message); ...

Offering a variety of choices for selecting elements in a single call while utilizing select2

I have incorporated the jQuery plugin select2 (Version 4) into my project and have applied it to all select elements using the following code: var select2_params = { minimumResultsForSearch: Infinity, templateResult: applyCategoryClasses, temp ...