使用JS中的扩展来扩展对象

时间:2016-12-17 17:53:39

标签: javascript design-patterns observer-pattern

有人可以向我解释这里发生了什么吗?

function extend( obj, extension ){
  for ( var key in extension ){
    obj[key] = extension[key];
  }
}

上下文:用于观察者模式https://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript

例如:

// Extend the controlling checkbox with the Subject class
extend( controlCheckbox, new Subject() );

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 );
  }
};

我的想法: for循环遍历我之前添加的Subject属性,然后将其添加到Observer-object。

我不理解的内容:为什么它只添加我之前添加的属性(即观察者,addObserver,removeObserver,notify),但不添加所有属性扩展对象?

例如,当我打印出扩展程序对象时,我可以看到constructor - 或__proto__属性已添加。

1 个答案:

答案 0 :(得分:2)

函数extend使obj继承extension的属性和方法。

因此,在这种情况下,controlCheckbox继承了Subject的属性和方法。

您将从Subject获取所有属性和方法,但__proto__不是属性或方法 - 它是查找链中用于解析方法等的实际对象。一篇好的帖子here,其中讨论了__proto__

<强>更新 事实上, proto 是一种财产 - 但它是一种特殊的财产。 From here

  

包含对指定对象的内部原型的引用。

     

一个对象只能有一个原型(不包括原型链中的继承原型)......

因此,在链中,__proto__ controlCheckbox,其__proto__ 的其中一个属性 __proto__来自Subjects,包含其所有属性和方法。

更新2 使用for (propName in obj)循环时,不会添加 proto 属性,因为它不可枚举。仅返回可枚举的继承属性。您可以搜索EnumerablepropertyIsEnumerable()以获取更多信息。