admin管理员组

文章数量:1278720

In the Apple "classs", how can the nested function countSeeds() retrieve the value this.price?

jsfiddle: /

Apple = function() {
    this.price = 17

    this.cutOpen = function() {

        console.log(this.price);
        countSeeds();

        function countSeeds() {
            console.log(this.price);
        }
    }        
}


var apple = new Apple();
apple.cutOpen();

Output

17
undefined

In the Apple "classs", how can the nested function countSeeds() retrieve the value this.price?

jsfiddle: http://jsfiddle/VGqEa/

Apple = function() {
    this.price = 17

    this.cutOpen = function() {

        console.log(this.price);
        countSeeds();

        function countSeeds() {
            console.log(this.price);
        }
    }        
}


var apple = new Apple();
apple.cutOpen();

Output

17
undefined
Share Improve this question asked Dec 22, 2013 at 1:41 NyxynyxNyxynyx 63.7k163 gold badges507 silver badges856 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 11

put var self = this at the top of Apple, and then refer to this as self instead in the nested function.

i.e.:

Apple = function() {
    var self = this;
    this.price = 17

    this.cutOpen = function() {

        console.log(this.price);
        countSeeds();

        function countSeeds() {
            console.log(self.price);
        }
    }        
}


var apple = new Apple();
apple.cutOpen();

You could also put the self=this statement at the beginning of this.cutOpen, since this will still refer to the Apple object in cutOpen (since it is a method of Apple).

Update

Most evergreen browsers now support arrow functions, so you can write it like:

Apple = function() {
    this.price = 17

    this.cutOpen = function() {

        console.log(this.price);
        let countSeeds = () => {
            console.log(this.price);
        };
        countSeeds();
    }        
}

This doesn't work in IE11 or other older browsers, unless you use some kind of transpiler to target older javascript.

By default, when you call a function without providing a context, this refers to window object. Try call or apply to set the context if you don't like the default:

this.cutOpen = function() {

        console.log(this.price);
        countSeeds.call(this); //use call to set the context for the function.

        function countSeeds() {
            console.log(this.price);
        }
    }  

I suggest that you move the countSeeds to outside the constructor function to prevent it from being redefined multiple times:

function countSeeds() {
            console.log(this.price);
        }

Apple = function() {
    this.price = 17

    this.cutOpen = function() {

        console.log(this.price);
        countSeeds.call(this);
    }        
}

Or define countSeeds as a prototype's function:

 Apple = function() {
        this.price = 17

        this.cutOpen = function() {

            console.log(this.price);
            this.countSeeds(); //use countSeeds as an instance method.
        }        
    }

    Apple.prototype.countSeeds = function () {
          console.log(this.price);
    }

In my opinion, countSeeds in this case should be an instance method as it always accesses the price property of the current instance and could not work if this is window

本文标签: javascriptUsing this for Parent Function inside a Nested FunctionStack Overflow