JavaScript: The Definitive Guide, Sixth Editio javaScript权威指南(第6版) pdf 文字版-文字版, javascript电子书, 和javascript 有关的电子书:

9.7.3 Composition Versus Subclassing

9.7.3 Composition Versus Subclassing

In the previous section, we wanted to define sets that restricted their members according to certain criteria, and we used subclassing to accomplish this, creating a custom subclass of a specified set implementation that used a specified filter function to restrict membership in the set. Each combination of superclass and filter function required the creation of a new class.

There is a better way to accomplish this, however. A well-known principle in object-oriented design is “favor composition over inheritance.”2 In this case we can use composition by defining a new set implementation that “wraps” another set object and forwards requests to it, after filtering out prohibited members. Example 9-15 shows how it is done.

Example 9-15. Composing sets instead of subclassing them


*A FilteredSet wraps a specified set object and applies a specified filter*to values passed to its add() method. All of the other core set methods*simply forward to the wrapped set instance. */ var FilteredSet = Set.extend(

function FilteredSet(set, filter) { // The constructor

this.set = set;

this.filter = filter;


{ // The instance methods

add: function() {

// If we have a filter, apply it

if (this.filter) {

for(var i = 0; i < arguments.length; i++) {

var v = arguments[i];

if (!this.filter(v))

throw new Error("FilteredSet: value " + v + " rejected by filter"); } }

// Now forward the add() method to this.set.add()

this.set.add.apply(this.set, arguments);

return this;


// The rest of the methods just forward to this.set and do nothing else.

remove: function() {

2. See Design Patterns by Erich Gamma et al. or Effective Java by Joshua Bloch, for example.

9.7 Subclasses | 233

this.set.remove.apply(this.set, arguments);

return this;


contains: function(v) { return this.set.contains(v); },

size: function() { return this.set.size(); },

foreach: function(f,c) { this.set.foreach(f,c); }


One of the benefits of using composition in this case is that only a single FilteredSet subclass is required. Instances of this class can be created to restrict the membership of any other set instance. Instead of using the NonNullSet class defined earlier, for example, we can do this:

var s = new FilteredSet(new Set(), function(x) { return x !== null; });

We can even filter a filtered set:

var t = new FilteredSet(s, { function(x} { return !(x instanceof Set); });

友情链接It题库(| 版权归yishouce.com所有| 友链等可联系|粤ICP备16001685号-1