title: Fabric.js New Class from existing Shape fromObject Error
body: <p>In my continuing saga of trying to make a custom class in Fabric.js that can be saved and loaded. I'm trying to extend the Line and Circle class and add some custom attributes... But I'm running to a problem when attempting to load the data. It saves ok, my simple 'name' attribute is there, but when attempting to load, I get stuck in the "enlivenObjects" function, namely where the klass gets that object type from the fabric.util.getKlass function. I get nothing back for my objects ("undefined").
  In the attached example, if you click "SAVE" the data for the canvas is put into a DIV, you can then "Clear" the canvas and try to "LOAD" the data. The error occurs when trying to load. 
  So, in a JS Console window, I can run "fabric.util.getKlass('Line')" and that works, I get an object back, but when I do the same with my 'namedCircle' or 'namedLine' I get undefined... 
  Any thoughts? Is this approach not going to work for me?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var canvas;
              
      window.onload = function() {
          canvas = new fabric.Canvas('c');
  
          /**
           * Attempt to make a custom Line, inherited from the fabric.Line
           * currently has a custom attribute of 'name'
           * 
           */
          fabric.namedLine = fabric.util.createClass(fabric.Line, {
              type: 'namedLine',
              initialize: function(points, options) {
                  options || (options = { });
                  this.callSuper('initialize', points, options);
                  this.set('name', options.name || '');
              },
              toObject: function() {
                  return fabric.util.object.extend(this.callSuper('toObject'), {
                  name: this.get('name')
                  });
              },
              fromObject: function(object, callback) {
                  return fabric.Object._fromObject('namedLine', options, callback);
              },
              _render: function(ctx) {
                  this.callSuper('_render', ctx);
              }
          });
  
          /**
           * Attempt at custom Circle, inherited from fabric.Circle with
           * a 'name' attribute.
           * 
           */
          fabric.namedCircle = fabric.util.createClass(fabric.Circle, {
              type: 'namedCircle',
              initialize: function(options) {
                  options || (options = { });
                  this.callSuper('initialize', options);
                  this.set('name', options.name || '');
              },
              toObject: function() {
                  return fabric.util.object.extend(this.callSuper('toObject'), {
                  name: this.get('name')
                  });
              },
              fromObject: function(object, callback) {
                  return fabric.Object._fromObject('namedCircle', object, callback);
              },
              _render: function(ctx) {
                  this.callSuper('_render', ctx);
              }
          });
          
          fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
  
          // First Create our line.
          var line = makeLine([ 250, 125, 250, 175 ], "myLine");
          canvas.add(line);
          
          // Now we create our circles, linking to our line.
          canvas.add(
              // first circle is at top of line, line1 is null, line2 is the line.
              makeCircle(line.get('x1'), line.get('y1'), "head", null, line),
  
              // second circle is at the bottom, line 1 is the line, nothing for line 2.
              makeCircle(line.get('x2'), line.get('y2'), "tail", line),
          );
  
          canvas.on('object:moving', function(e) {
              var p = e.target;
              // set bottom of the line to the shapes left and top position.
              p.line1 &amp;&amp; p.line1.set({ 'x2': p.left, 'y2': p.top });
              // set the top to the line to the circle position.
              p.line2 &amp;&amp; p.line2.set({ 'x1': p.left, 'y1': p.top });
              canvas.renderAll();
          });
  
          // Add our button events.
          document.getElementById("btnSave").addEventListener("click", saveData);
          document.getElementById("btnLoad").addEventListener("click", loadData);
          document.getElementById("btnClear").addEventListener("click", clearData);
  
      };
  
      // our circle has up to 2 links.
      function makeCircle(left, top, name, line1, line2) {
          var c = new fabric.namedCircle({
              left: left,
              top: top,
              strokeWidth: 5,
              radius: 12,
              fill: '#fff',
              stroke: '#666',
              name: name
          });
          c.hasControls = c.hasBorders = false;
  
          c.line1 = line1;
          c.line2 = line2;
  
          return c;
      }
  
      function makeLine(coords, name) {
          return new fabric.namedLine(coords, {
              fill: 'red',
              stroke: 'red',
              strokeWidth: 5,
              selectable: false,
              name: name
          });
      }
  
      function saveData() {
          document.getElementById("out").innerHTML = "";
          document.getElementById("out").innerHTML = JSON.stringify(canvas.toDatalessJSON());
      };
  
      function loadData() {
          var data = document.getElementById("out").innerHTML;
          console.log(data);
          canvas.loadFromDatalessJSON(data);
          canvas.renderAll();
      };
  
      function clearData() {
          canvas.clear();
      }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>#out {
      width:500px;
      height:300px;
      border:1px solid red;
      overflow:scroll;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"&gt;&lt;/script&gt;
  &lt;canvas style="border: 2px solid; " height="500" width="600" id="c"&gt;&lt;/canvas&gt;
  &lt;p&gt;
    &lt;button id="btnSave"&gt;Save&lt;/button&gt;
    &lt;button id="btnClear"&gt;Clear&lt;/button&gt;
    &lt;button id="btnLoad"&gt;Load&lt;/button&gt;
  &lt;/p&gt;
  &lt;div id="out"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>