views:

100

answers:

1

I've used Douglass Crockford's Object.beget, but augmented it slightly to:

Object.spawn =  function (o, spec) {
  var F = function () {}, that = {}, node = {};
  F.prototype = o;
  that = new F();
  for (node in spec) {
    if (spec.hasOwnProperty(node)) {
      that[node] = spec[node];
    }  
  }
  return that;
};

This way you can "beget" and augment in one fell swoop.

var fop = Object.spawn(bar, {
  a: 'fast',
  b: 'prototyping'
});

In English that means, "Make me a new object called 'fop' with 'bar' as its prototype, but change or add the members 'a' and 'b'. You can even nest it the spec to prototype deeper elements, should you choose.

var fop = Object.spawn(bar, {
  a: 'fast',
  b: Object.spawn(quux,{
    farple: 'deep'
  }),
  c: 'prototyping'
});

This can help avoid hopping into an object's prototype unintentionally in a long object name like:

  foo.bar.quux.peanut = 'farple';

If quux is part of the prototype and not foo's own object, your change to 'peanut' will actually change the protoype, affecting all objects prototyped by foo's prototype object.

But I digress... My question is this. Because your spec can itself be another object and that object could itself have properties from it's prototype in your new object - and you may want those properties...(at least you should be aware of them before you decided to use it as a spec)...

I want to be able to grab all of the elements from all of the spec's prototype chain, except for the prototype object itself... This would flatten them into the new object.

Currently I'm using...

Object.spawn =  function (o, spec) {
  var F = function () {}, that = {}, node = {};
  F.prototype = o;
  that = new F();
  for (node in spec) {
    that[node] = spec[node]; 
  }
  return that;
};

I use it for every object I prototype, but because i use it so much, I'm looking to hone it down to the best possible.... I would love thoughts and suggestions...

A: 

If I've understood your question properly, you're asking how to use an approach like the one you have provided, but still be able to access prototype properties when they are overridden by the spec?

One way to get around the problem of inaccessible (overridden) prototype properties is to add them to the object along with the spec, but namespace them.

This example show how you could add the overridden to the object by prefixing it with an underscore. Put your namespacing of choice in it's place! (for example, you could use a 'super' property on the object)

Object.spawn =  function (o, spec) {
  var F = function () {}, that = {}, node = {};
  F.prototype = o;
  that = new F();
  for (node in spec) {
    if("undefined" !== typeof o[node]) {
      that['_' + node] = o[node];
    }
    that[node] = spec[node]; 
  }
  return that;
};
adamnfish