0

Referring to this question: Understanding better Javascript OOP architecture

Angular sets a closure variable called self to this. Later it's used in handleLocationChange to find the right this. I've looked at the code but can't find any example where handleLocationChange is called or registered.

In my answer to the above mentioned question I speculate that it's declared in the constructor's body because the event/publish/subscribe implementation will be passed handleLocationChange without the instance it's on so when it's called it can't use .call or .apply because the specific instance isn't known.

Maybe someone with Angular experience could explain how handleLocationChange is used, where is the function registered and why isn't it on the Dialog's prototype?

function Dialog(opts) {

            var self = this, options = this.options = angular.extend({}, defaults, globalOptions, opts);
            this._open = false;

            this.backdropEl = createElement(options.backdropClass);
            if(options.backdropFade){
                // ...
            }

            this.handleLocationChange = function() {
                self.close();
            };

            // more functions
        }

I speculated handleLocation (and other functions) are declared within the constructor's body instead of the prototype because of the following situation:

var eventSystem={
  events:{},
  add:function(eventname,fnCallback){
     if(!this.events[eventname]){
      this.events[eventname]=[];
     }
     this.events[eventname].push(fnCallback);
  },
  trigger:function(eventname){
    if(!this.events[eventname]){
      return;
    }
    var i=0;
    for(i=0;i<this.events[eventname].length;i++){
      this.events[eventname][i]();
    }
  }
};

var person=function(name){
  this.name=name;
};
person.prototype.sayName=function(){
  console.log("this is now:",this.toString());
    // logs this is now: function (){ console.log("this is now:...
    // so this is now the sayName function not the person instance
  console.log(this.name);//undefined: sayName doesn't have a name property
}
var jon=new person("jon");
eventSystem.add("sayname",jon.sayName);//add event and listener function
eventSystem.trigger("sayname");//trigger the event

Here is how it's solved setting a closure reference

var eventSystem={
  events:{},
  add:function(eventname,fnCallback){
     if(!this.events[eventname]){
      this.events[eventname]=[];
     }
     this.events[eventname].push(fnCallback);
  },
  trigger:function(eventname){
    if(!this.events[eventname]){
      return;
    }
    var i=0;
    for(i=0;i<this.events[eventname].length;i++){
      this.events[eventname][i]();
    }
  }
};

var person=function(name){
  var self=this;// set closure ref to this
  this.name=name;
  this.sayName=function(){
    console.log(self.name);//use closure ref to get this
       // logs jon
  }
};
var jon=new person("jon");
eventSystem.add("sayname",jon.sayName);//add event and listener function
eventSystem.trigger("sayname");//trigger the event
4

0 回答 0