-2
function Machine() {
    this._enabled = false;
    var self = this;

    this.enable = function() {
        self._enabled = true;
    };

    this.disable = function() {
        this._enabled = false;
    };
}

function CoffeeMachine() {
    Machine.apply(this, arguments);

    var parentEnable = this.enable;
    this.enable = function() {
        parentEnable();
        /// this.run();
    }
}
var coffeeMachine = new CoffeeMachine();
coffeeMachine.enable();

In parentEnable copied function from this.enable. In Machine var self = this; - self here refers to the created object constructor CoffeeMachine. When called parentEnable(), how this challenge? After all, the local variable self function Machine. A parentEnable() called at all in CoffeeMachine().

Aleksandr
  • 439
  • 3
  • 13
  • 3
    Your sentences don't make much sense... What's your question? – orange Jan 30 '15 at 22:40
  • Agreed with orange, your question is hard to understand. Do I understand you correctly that you're wondering how CoffeeMachine has access to the `self` variable defined in Machine? – Azeirah Jan 30 '15 at 22:43
  • Sasha, try to use the googe translate service to translate russian to english. – Ruben Kazumov Jan 30 '15 at 22:43
  • @RubenKazumov, I already use them – Aleksandr Jan 30 '15 at 22:47
  • 2
    When you call `Machine.apply(this, arguments);`, you are explicitly setting the `this` value inside `Machine` to the first argument passed to `.apply`. I.e. `this` inside `CoffeeMachine` is the same as `this` inside `Machine` which is the same as `self` inside `Machine`. – Felix Kling Jan 30 '15 at 23:01
  • @FelixKling, thank you very much for your explanation. I still misleading the fact that self, the local variable functions Machine. – Aleksandr Jan 30 '15 at 23:17
  • Enable and disable are closures so they have acces to self which in turn is this which is set by Machine using apply (can also be done using call). Although the following answer does not use such patterns to simulate private instance specific values with functions that can access them it may still be useful to you: http://stackoverflow.com/a/16063711/1641941 – HMR Jan 31 '15 at 02:14

2 Answers2

1

Any function, when called, will introduce a new scope, in this case, when Machine gets called at your line Machine.apply(this, arguments), you're introducing a new scope.

Every and any function defined inside that scope will have access to every variables inside their own scope, and the outer scope (variables defined inside Machine)

So technically, CoffeeMachine doesn't have access to self, Machine's enable and disable functions do however, and CoffeeMachine has access to those functions.

Azeirah
  • 6,176
  • 6
  • 25
  • 44
1

it's all about prototype chain buddy

self here refers to the created object constructor

No,here self refers to created instances of the constructor not the constructor itself.Otherwise it is the global window object.

Machine.apply(this);

this statement makes coffeeMachine inherit all the methods and properties form Machine constructor.So ,it creates a parent-child relationship betwween those two where Machine is the parent class and coffeeMachine is child class.

it creates a prototype chain between them.If you are looking for a property or method on child instances ,but it is not defined in the child constructor ,interpreter goes down below the prototype chain looking for it.If it finds inside parents constructor ,then that property/method's value is used

inside coffeMachine this refers to global object.When you create new instance of coffeeMachine then this refers to the newly created object. When you create a new instance of coffeeMachine var parentEnable = this.enable; looks for this.enabled in the prototype chain.

As this.enabled method is preceded by var parentEnable=this.enabled It doesn't find it in the coffeMachine constructor .So it looks deep inside the prototype chain and finds it in parent.Thats how parent's this.enabled is assigned to var parentEnable.

if coffeeMachine's this.enabled is defined before the var parentEnabled then coffeMachine's this.enabled function will be assigned to parnetEnabled

function CoffeeMachine() {

    Machine.apply(this);
    this.enable = function() {
        parentEnable();
        /// this.run();
    }
    var parentEnable = this.enable; // it is now function(){parentEnable();///this.run()};


}
var coffeeMachine = new CoffeeMachine();
coffeeMachine.enable();

These two links have good explanatin about prototype chain in javascript:

AL-zami
  • 8,902
  • 15
  • 71
  • 130