3

I wanted to pass many variables to child functions and that passed variables should also pass on to the next child functions. Passing them each time as parameters is a tedious job. I was wondering what would be the better way to do this in Js. I tried using the this keyword , But not sure if that is the correct way of usage to achieve this.

var scriptConfig = {
  availableOptions: {
    version: "1",
    type: "one",
    status: "free",
  },
  availableCategories: {
    navbar: true,
    hasCoupon: true
  }
};

window.addEventListener('load', function() {
  let options = scriptConfig.availableOptions;
  let version = options.version;
  renderDashboard(options, version);
});

function renderDashboard(options, version) {
  createNavbar(options, version);
}

function createNavbar(options, version) {
  console.log(options);
  console.log(version);
}

Using this

var scriptConfig = {
  availableOptions: {
    version: "1",
    type: "one",
    status: "free",
  },
  availableCategories: {
    navbar: true,
    hasCoupon: true
  }
};

window.addEventListener('load', function() {
  this.options = scriptConfig.availableOptions;
  this.version = options.version;
  this.renderDashboard();
});

function renderDashboard() {
  this.createNavbar();
}

function createNavbar() {
  console.log(this.options);
  console.log(this.version);
}

Can anyone suggest which would be a better way ? Also it would be great if anyone suggest better coding practice for the above lines of code.

3 Answers 3

1

Using this in global scope (outside class) is not a good idea as it pollute the Window object. I will suggest you to create a class and wrap everything like this:

class Dashboard {
    constructor(config) {
        this.options = config.availableOptions;
        this.version = this.options.version;
    }

    renderDashboard() {
        this.createNavbar();
    }

    createNavbar() {
        console.log(this.options, this.version);
    }
}

var scriptConfig = {
    availableOptions: {
        version: "1",
        type: "one",
        status: "free",
    },
    availableCategories: {
        navbar: true,
        hasCoupon: true
    }
};

window.addEventListener('load', function () {
    const dashboard = new Dashboard(scriptConfig);
    dashboard.renderDashboard();
});
Sign up to request clarification or add additional context in comments.

4 Comments

Thank You. But I would like to use the options and version variable in other functions too , not only in createNavbar() , so where can it be declared as global ?
You can all variables inside constructor and can use within any function of same class. constructor(config) { this.options = config.availableOptions; this.version = this.options.versions; }
ok , Is it a typo - this.config.availableOptions , shouldn't it be this.scriptConfig.availableOptions. You have used config instead of scriptConfig ?
No, if you will check the constructor(config){ } then it receive argument as config, and I updated my comment.
1

There is [apply()][1] function in JS.

It lets you specify what this is when calling a function and provide additional arguments.

Comments

1

Well if you are constantly passing a variable from one function to its child functions, or in other terms from one ui component to its ui component, what you are doing in this case is sharing context between these entities (functions, components, or call them whatever you want depending on the type of their output)

global variables should be avoided, however in certain use cases they are the only valid solution, one use case for global variables are contexts - some people differentiate between context and global state, in that a context is a read only, while global state is mutable, for managing global states, javascript has many libraries that handle this like redux.

Assuming that you are using an immutable context, then the best option is a global variable, obviously you should hide that global variable behind a getter function to also make code more decelarticve

// Assuming you are using javascript modules if not just remove the export keyword
// obviously add the needed properties for the object
const globalContext = Object.freeze({}) // freeze object to prevent mutations to it
export const getGlobalContext = () => {
    // hiding the global variable behind a getter offers two advantages, it better conveys the message that this object should not mutated by code
    // later it enables more customization of context sharing, if for example later you decide to nest contexts, but if your context will get complicated, then doing that through a library should be better option
    return globalContext;
}

Finally dont use the this keyword outside of instances/classes context, this will produce poor code that is hard to read, and more prone to errors, and its one of the reasons ES6 added the syntatic sugar class to make code that uses this only use it there and not in normal functions ( though it is still valid syntax)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.