Can someone explain to me what is happening here?
function extend( obj, extension ){
for ( var key in extension ){
obj[key] = extension[key];
}
}
Context: Used in the Observer Pattern https://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript
For example:
// Extend the controlling checkbox with the Subject class
extend( controlCheckbox, new Subject() );
With
function Subject(){
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function( observer ){
this.observers.add( observer );
};
Subject.prototype.removeObserver = function( observer ){
this.observers.removeAt( this.observers.indexOf( observer, 0 ) );
};
Subject.prototype.notify = function( context ){
var observerCount = this.observers.count();
for(var i=0; i < observerCount; i++){
this.observers.get(i).update( context );
}
};
What I think is going on: The for loop goes through the Subject's properties that I added before and then adds it to the Observer-object.
What I don't understand: How come it only adds those properties that I added before (i.e. observers, addObserver, removeObserver, notify) but not ALL properties of the extension object?
For example when I print out the extension object I can see that the constructor- or the __proto__ property is NOT added.
The function
extendis makingobjinherit the properties and methods ofextension.So, in this case,
controlCheckbox, is inheriting the properties and methods ofSubject.You will get all the properties and methods from
Subjectbut__proto__is not a property or method - it is the actual object that is used in the lookup chain to resolve methods, etc. There is a good post here which discusses__proto__UPDATE Indeed, proto is a property - but it is a special kind of property. From here:
So in the chain, you will have a
__proto__forcontrolCheckboxand one of the properties of its__proto__should be the__proto__fromSubjectscontaining all its properties and methods.UPDATE 2 When using
for (propName in obj)loops, the proto property is not added because it is not enumerable. Only enumerable inherited properties are returned. You can search onEnumerableandpropertyIsEnumerable()to get more information.