OOP. Calling methods from within methods

前端 未结 4 2010
一生所求
一生所求 2021-01-19 19:30

How do I call class methods from functions within the class? My code is:

var myExtension = {

    init: function() {
        // Call onPageLoad
    },  

            


        
相关标签:
4条回答
  • 2021-01-19 19:59

    The object the current method was invoked on is available via the special variable this. Any time you call a method on an object, this will refer, within the method, to the object.

    var myExtension = {
    
        init: function() {
            this.onPageLoad();
        },  
    
        onPageLoad: function() {  
            // Do something    
        },
    
    };
    

    this always refers to the calling object rather than the object the function is defined on or is a property of.

    value = 'global';
    var ob0 = {
            value: 'foo',
            val: function() {
                return this.value;
            },
        },
        ob1 = {value: 'bar'},
        ob2 = {value: 'baz'};
    
    ob0.val(); // 'foo'
    ob1.val = ob0.foo;
    ob1.val(); // 'bar'
    ob0.val.call(ob2); // 'baz'
    
    var val = ob0.val;
    val(); // 'global'
    

    In the last case, val is executed as a free function (a function that isn't bound to an object, i.e. not a method), in which case this takes on the value of the global object (which is window in web browsers) within the execution of val. Global variables are actually properties of the global object, hence val() returns 'global' (the value of the global variable named value). Since global variables are actually properties of the global object, you can view free functions as actually being methods of the global object. From this viewpoint, the last two lines (when executed in global scope) are equivalent to:

    window.val = ob0.val;
    window.val();
    

    This viewpoint doesn't exactly match the reality of scoping, though you'll only notice the difference within functions. In a function, window.val = ... will create a global while var val won't.

    value = 'global';
    var ob0 = {
            value: 'foo',
            val: function() {
                return this.value;
            },
        };
    
    function lcl() {
        var val = ob0.val; // doesn't set a global named `val`
        return val(); // 'global'
    }
    lcl(); // 'global'
    val(); // error; nothing named 'val'
    
    function glbl() {
        window.val = ob0.val; // sets a global named `val`
        return window.val();  // 'global'
    }
    glbl(); // 'global'
    val(); // 'global'
    

    See MDN's reference page for more on the call method used above. For more on the this variable, see "JavaScript “this” keyword" and "How does “this” keyword work within a JavaScript object literal?"

    0 讨论(0)
  • 2021-01-19 20:00

    In Javascript you need to explicitly mention the this

    this.onPageLoad()
    

    The same is also true for other member variables (remember that in Javascript methods are just member variables that happen to be functions)

    this.memberVariable
    
    0 讨论(0)
  • 2021-01-19 20:15

    Have you considered a closure, instead?

    For example:

    var myExtension = ( function() {
    
        var me = {};
    
        var private_thingy = "abcDEFG123";
    
    
        var onPageLoad = function() {
            // do page loading business
            alert( private_thingy );
        }
        me.onPageLoad = onPageLoad;
    
    
        var init = function() {
            onPageLoad();
        }
        me.init = init;
    
    
        return me;
    
    })();
    
    ///////////////
    
    myExtension.private_thingy = "DIDDLED!";
    // will NOT modify the private_thingy declared within the closure
    
    myExtension.init(); // will work fine.
    

    Anything you define within the closure is available within the closure at all times, and when implemented carefully will yield private members not accessible to users of the object. Only members that you explicitly export - e.g., the me.xxx = xxx lines - are publicly available.

    Thus, when onPageLoad executes, "abcDEFG123" will be displayed in the alert, not "DIDDLED!". Users of the object can modify properties using the dot operator until the cows come home; what's not made public by the closure, however, can never be modified: even if the user reassigns a function on the public interface, calls to the private function from within the closure will always point to the function defined within the closure.

    The important part: it unties you from the constant use of this (unless you really want to use it; save your fingers for more important typing!).

    Give it a shot. And have a look at Javascript: The Good Parts by Crockford.

    0 讨论(0)
  • 2021-01-19 20:24

    Assuming that you have called init like this:

    myExtension.init();
    

    then it should be:

    init: function() {
        // before
        this.onPageLoad();
        // after
    }
    

    But in Javascript functions are not actually bound to objects and you can call any function on any other object, like this:

    myExtension.init.call(anotherObject); // or
    myExtension.init.apply(anotherObject);
    

    In this example this within init would be anotherObject, which doesn't have onPageLoad defined. If you want to support this kind of usage you'll have to manually reference the initial object:

    init: function() {
        // before
        myExtension.onPageLoad();
        // after
    }
    
    0 讨论(0)
提交回复
热议问题