Making JS local function globally accessible

2020-07-10 07:46发布

问题:

I have a function inside a function that I need to access directly.

//#############################################################
//# Global vars
//#############################################################
var canvasWidth = 585;
var canvasHeight = 780;

//#############################################################
//# Init the canvas
//#############################################################
window.onload = function() {
    initStage();
};

//#############################################################
//# Init the main stage
//#############################################################
function initStage() {

    //*************************************************************
    //* Create a stage to work with
    //*************************************************************
    var stage = new Kinetic.Stage({
        container: "container",
        width: canvasWidth,
        height: canvasHeight
    });

    var layerOne = new Kinetic.Layer();
    var imageObj = new Image();

    //*************************************************************
    //* Load the image into a layer on the stage
    //*************************************************************
    ... Some Code ...

    //*************************************************************
    //* Set the hidden field value to the canvas dataURL
    //*************************************************************
    function autoSave(){
        stage.toDataURL({
            callback: function(dataUrl){
                document.getElementById("mapping-form:hiddenDataURL").value = dataUrl;
                console.log("Auto Save excecuted");
            }, 
            mimeType: 'image/jpeg', 
            quality: 1.0
        });        
    }

    //*************************************************************
    //* Function called to add text to the stage
    //*************************************************************
    ... Some Code ...    

        layerTwo.add(txt);
        stage.add(layerTwo);

    });

}

I'm trying to access autoSave() (that in return requires the stage var from the parent function). I understand why I can't access it, but Im struggling to see how I can alter the code to make it accessible.

My first thought was simply to declare a 'higher scoped' var and assign the function to it. The problem is (as far as I can see) that this doesn't actually allow me to execute the autoSave() at the requested time.

Apologies for the 'basic natur of this question, I'm new to JS and I think this is going to be fundamental!

回答1:

You can make your function globally accessible and still keep reference to variables in the scope in which it was created. Simply create and assign it in window scope - e.g. instead of defining it as:

function autoSave() {
    // ... code ...
}

declare it as:

window.autoSave = function() {
    // .... code ....
}

you will now be able to call it anywhere (provided the initStage method has been called to declare it first, of course).



回答2:

You can assign the autoSave function to the this object, i.e.

function initStage() {        
    ... Some Code ...
    this.autoSave = function(){
        ... Some Code ...        
    }

    return this;
}

Now you can call

initStage().autoSave();


回答3:

As you can see here the autoSave is called with no problem. I believe that the problem is in the rest of the code. You have }); in the bottom of the script which doesn;t open anywhere

The code is as simple as possible

window.onload = function() {
    initStage();
};

function initStage() {
    alert('a');

    function autoSave() {
        alert('b');
    }

    autoSave();
}


回答4:

You Can Access Your local function as mentioned below

var myFunc = function () {
  //Local Scope
  this.scopeLocal = function () {
    alert("yipee!!! You Can Call Me");
  }
}

var myfunc = new myFunc();//Create a Object

window.onload = function () {
  myfunc.scopeLocal(); // Call it Globally
};

Check out Demo here : http://jsbin.com/efojom/1/edit



回答5:

Generally I would suggest something like this: You can use your personal namespace to make functions and objects available.

// make a scope wrapper to keep vars local
(function () {
    // your module vars available within this scope
    var canvasWidth = 585;
    var canvasHeight = 780;

    // create a namespace
    var myspace = {
        stage: new Kinetic.Stage({
            container: "container",
            width: canvasWidth,
            height: canvasHeight
        },
        autoSave: function () {
            this.stage.toDataURL({
                callback: function(dataUrl){
                    document.getElementById("mapping-form:hiddenDataURL").value = dataUrl;
                    console.log("Auto Save excecuted");
                }, 
                mimeType: 'image/jpeg', 
                quality: 1.0
            });
        }
    };

    var layerOne = new Kinetic.Layer();
    var imageObj = new Image();

    layerTwo.add(txt);
    myspace.stage.add(layerTwo);


    // finally export to global namespace only what you really need
    window["myspace"] = myspace;
});

// then from anywhere, just call this

myspace.autosave();
myspace.stage;