makeNotify = function makeNotify(num) {
  return function () {
    var _this = this;

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    var opts = args[args.length - num];
    var op = opts.op;
    this.dbg.apply(this, [op].concat(args));

    if (applyDefaultsHooks.indexOf(op) !== -1 && opts.applyDefaults !== false) {
      var schema = this.getSchema();

      if (schema && schema.applyDefaults) {
        var toProcess = args[0];

        if (!utils.isArray(toProcess)) {
          toProcess = [toProcess];
        }

        toProcess.forEach(function (record) {
          schema.applyDefaults(record);
        });
      }
    } // Automatic validation


    if (validatingHooks.indexOf(op) !== -1 && !opts.noValidate) {
      // Save current value of option
      var originalExistingOnly = opts.existingOnly; // For updates, ignore required fields if they aren't present

      if (op.indexOf('beforeUpdate') === 0 && opts.existingOnly === undefined) {
        opts.existingOnly = true;
      }

      var errors = this.validate(args[op === 'beforeUpdate' ? 1 : 0], utils.pick(opts, ['existingOnly'])); // Restore option

      opts.existingOnly = originalExistingOnly; // Abort lifecycle due to validation errors

      if (errors) {
        var err = new Error('validation failed');
        err.errors = errors;
        return utils.reject(err);
      }
    } // Emit lifecycle event


    if (opts.notify || opts.notify === undefined && this.notify) {
      setTimeout(function () {
        _this.emit.apply(_this, [op].concat(args));
      });
    }
  };
}
Create a subclass of this Schema:
@example <caption>Schema.extend</caption>
const JSData = require('js-data');
const { Schema } = JSData;
console.log('Using JSData v' + JSData.version.full);

// Extend the class using ES2015 class syntax.
class CustomSchemaClass extends Schema {
  foo () { return 'bar'; }
  static beep () { return 'boop'; }
}
const customSchema = new CustomSchemaClass();
console.log(customSchema.foo());
console.log(CustomSchemaClass.beep());

// Extend the class using alternate method.
const OtherSchemaClass = Schema.extend({
  foo () { return 'bar'; }
}, {
  beep () { return 'boop'; }
});
const otherSchema = new OtherSchemaClass();
console.log(otherSchema.foo());
console.log(OtherSchemaClass.beep());

// Extend the class, providing a custom constructor.
function AnotherSchemaClass () {
  Schema.call(this);
  this.created_at = new Date().getTime();
}
Schema.extend({
  constructor: AnotherSchemaClass,
  foo () { return 'bar'; }
}, {
  beep () { return 'boop'; }
});
const anotherSchema = new AnotherSchemaClass();
console.log(anotherSchema.created_at);
console.log(anotherSchema.foo());
console.log(AnotherSchemaClass.beep());

@method Schema.extend
@param {object} [props={}] Properties to add to the prototype of the
subclass.
@param {object} [props.constructor] Provide a custom constructor function
to be used as the subclass itself.
@param {object} [classProps={}] Static properties to add to the subclass.
@returns {Constructor} Subclass of this Schema class.
@since 3.0.0