Refer to javascript function from within itself

后端 未结 12 863
失恋的感觉
失恋的感觉 2020-12-24 06:08

Consider this piece of code

var crazy = function() {
    console.log(this);
    console.log(this.isCrazy); // wrong.
}
crazy.isCrazy = \'totally\';
crazy();
         


        
相关标签:
12条回答
  • 2020-12-24 06:48

    You have to give it its own name, so:

    var crazy = function() {
        console.log(crazy);
        console.log(crazy.isCrazy);
    }
    crazy.isCrazy = 'totally';
    crazy();
    

    The variable this is only applicable in the scope of an object, for instance, if you invoked your version of the crazy function with crazy.call(crazy), it will call the function in the context of the function crazy and all would be well.

    0 讨论(0)
  • 2020-12-24 06:48

    Funny that you should ask, mate. I just went through this same issue for a different purpose. The quick version of the final code is:

    $a = function() {};
    
    $ = function() {
        if (!(this instanceof $)) {
            return new $();
        }
    
        this.name = "levi";
    
        return this;
    };
    
    //helper function
    var log = function(message) {
        document.write((message ? message : '') + "<br/>");
    };
    
    log("$().name == window.name: " + ($().name == window.name)); //false
    log("$().name: " + $().name); //levi
    log("window.name: " + window.name); //result
    
    log();
    
    log("$a instanceof $: " + ($a instanceof $)); //false
    log("typeof $a: " + (typeof $a)); //function
    log("typeof $: " + (typeof $)); //function
    

    The critical piece:

        if (!(this instanceof $)) {
            return new $();
        }
    

    If this isn't pointing to an object of the right type, then it makes a new one, which will properly scope this. The rest of the code is just there for verification that it does indeed work as intended.

    0 讨论(0)
  • 2020-12-24 06:51

    In order to make you code to work follow below

            function crazy_object (crazy) {
              this.isCrazy = crazy
            }
            
            var create_crazy = new crazy_object('hello') //creating object
            
            console.log(create_crazy); //=> { isCrazy = 'hello' }
            
            var crazy = function() {
                console.log(this); //=> { isCrazy = 'totally' }
                console.log(this.isCrazy); //=> 'totally'
            }
            
            create_crazy.isCrazy = 'totally'; //=> isCrazy = 'totally'
            //below we pass the created object in function crazy.
            //And doing that we can use the keywork `this` and refer to the object
            crazy.call(create_crazy, null);

    Using the call and apply method we can pass to a function a property,and in that function we can use the property with the keyword this

    For example:

    function speak (message) {
      console.log(`A person with name ${this.name} say ${message}`);
    }
    
    speak.call({ name: 'Roland' }, 'Javascript is awesome');

    To use it with property:

    function speak (message) {
      console.log(`A person with name ${this.name} say ${message}`);
    }
    
    var name = 'Roland'
    
    speak.call({ name }, 'Javascript is awesome');
    
    0 讨论(0)
  • 2020-12-24 06:52

    You can use the call method

    var crazy = function() {
        console.log(this);
        console.log(this.isCrazy);
    }
    crazy.isCrazy = 'totally';
    crazy.call(crazy);
    // calls crazy using crazy as the target, instead of window:
    // functionToCall.call(objectToUseForThis);
    

    Though if your function only ever has one name, you can do this:

    var crazy = function() {
        console.log(crazy);
        console.log(crazy.isCrazy);
    }
    crazy.isCrazy = 'totally';
    crazy();
    
    0 讨论(0)
  • 2020-12-24 06:55

    Bind the function to itself (taking a hint from answers by @ArunPJohny and @BudgieInWA):

    crazy = crazy.bind(crazy);
    

    This will give you access from the function to its properties via this.

    > crazy()
    function () {
        console.log(this);
        console.log(this.isCrazy); // works now
    }
    

    This seems like a better solution than the accepted answer, which uses the callee feature which is deprecated and doesn't work in strict mode.

    You could also now have the function call itself recursively with this() were you so inclined.

    We will call this self-thisifying. Write a little utility function:

    function selfthisify(fn) { return fn.bind(fn); }
    crazy = selfthisify(crazy);
    crazy();
    

    Or, if you prefer more "semantic" names, you could call it accessOwnProps.

    If you're a syntactic sugar type of person, you could add a selfthisify property to the Function prototype:

    Object.defineProperty(Function.prototype, 'selfthisify', {
        get: function() { return this.bind(this); }
    });
    

    Now you can say

    crazy.selfthisify();
    
    0 讨论(0)
  • 2020-12-24 06:55

    Personally I feel that the correct way to use a function inside of a function would be to use a constructor inside of a constructor, because of the keyword 'this':

        this;
    

    Defining functions and reusing them within themselves gives the developer no control over scopes. In a real-life use-case, even it everything looked as if the function called within its-self seemed to be working perfectly, there is no way in h*ll I would put it into a production piece of code. By creating an object and assigning parameter values to variables using the 'this' key word like so:

        new SumObj{
          constructor(delta, epsilon, zeta){
              this.delta = delta;
              this.epsilon = epsilon;
              this.zeta = zeta;
          }
        }
    

    You are essentially controlling the scopes of the different layers of variables that have the same name. Not controlling the scopes of variables in such a case is very likely to cause the developer much grief.

        new SumObj('someStr', 300, true);
    

    Using an Object in such a way will create a new instance with a unique scope of its own, therefore; this allows you to trust the values of your variables, and you will not get surprise results.

    • Bellow is a very simple use, that is actually practical to use in a real world app. I use an object similar to this for printing when testing Node.JS projects I am working on.

    class PrintObj {
        constructor(obj) {
            this.vals = Object.values(obj);
            this.keys = Object.keys(obj);
    
            for(let i = 0; i < this.vals.length; i++) {
                const el = this.vals[i];
    
                if(typeof el === 'object'){ 
                    new PrintObj(el);
                } else {
                    console.log(`\t ${this.keys[i]} : ` + el);
                }
            }
        }
    }
    
    const sumObj = {
        alpha: 'Hello World!',
        beta: 'Hello From Universe!',
        gamma: 'Hello Developers!',
        delta: {
            a: '0',
            b: '1',
            c: '2',
            e: '3',
            f: '4',
        },
        epsilon : 'Hello Mum',
        zeta : 'Hello Papa'
    };
    new PrintObj(sumObj);

    0 讨论(0)
提交回复
热议问题