понедельник, 17 августа 2015 г.

JavaScript - Новые шаблоны наследования

// Get и Set

function Vehicle(make, year) {
  Object.defineProperty(this, 'make', {
    get: function() { return make; }
  });

  Object.defineProperty(this, 'year', {
    get: function() { return year; }
  });
}

Vehicle.prototype.toString = function() {
  return this.make + ' ' + this.year;
}

Vehicle.compare = function(a, b) {
  // ...
}

// Extending

function Motorcycle(make, year) {
  Vehicle.apply(this, [make, year]);
}

Motorcycle.prototype = Object.create(Vehicle.prototype, {
  toString: function() {
    return 'Motorcycle ' + this.make + ' ' + this.year;
  }
});

Motorcycle.prototype.constructor = Motorcycle;

Motorcycle.compare = function(a, b) {
  // ...
}

// ES6

class Motorcycle extends Vehicle {
  constructor(make, year) {
    super(make, year);
  }

  toString() {
    return 'Motorcycle ' + super.toString();
  }
}

// Interface

function createInterface(name) {
  return class {
    ['findBy' + name]() {
      return 'Found by ' + name;
    }
  }
}

const Interface = createInterface('Email');
const instance = new Interface();

console.log(instance.findByEmail());
class Vehicle {
  static compare(a, b) {
    // ...
  }
}

class Motorcycle {
  static compare(a, b) {
    if (super.compare(a, b)) {
      // ...
    }
  }
}

// Proxy

Функция прокси может легко дополнить конструктор новым:

function extend(sup,base){
    var descriptor=Object.getOwnPropertyDescriptor(base.prototype,"constructor");
    base.prototype=Object.create(sup.prototype);
    var handler={
        construct:function(target,args){
            var obj=Object.create(base.prototype);
            this.apply(target,obj,args);
            return obj;
        },
        apply:function(target,that,args){
            sup.apply(that,args);
            base.apply(that,args);
        }
    };
    var proxy=new Proxy(base,handler);
    descriptor.value=proxy;
    Object.defineProperty(base.prototype,"constructor",descriptor);
    return proxy;
}

var Person=function(name){
    this.name=name
};

var Boy=extend(Person,function(name,age){
    this.age=age;
});
   
Boy.prototype.sex="M";

var Peter=new Boy("Peter",13);
console.log(Peter.sex); // "M"
console.log(Peter.name); // "Peter"
console.log(Peter.age); // 13

// Parent

var ParentClass = function (parentInitVar) {
    this._parentInitVar = parentInitVar;
};

ParentClass.prototype.parentPublicMethod = function () {};

Object.defineProperty(ParentClass.prototype, 'parentInitVar', {
      get: function() {return _parentInitVar;}
    , set: function(value) {this._parentInitVar = value;}
});

ParentClass.parentStaticMethod = function () {};

// Child

var ChildClass = function (childInitVar) {
    ParentClass.apply(this, [childInitVar]);
};

ChildClass.prototype.childPublicMethod = function () {};

Object.defineProperty(ChildClass.prototype, 'parentInitVar', {
      get: function() {return _parentInitVar;}
    , set: function(value) {this._parentInitVar = value;}
});

ChildClass.childStaticMethod = function () {};


// Extend

var Child = extend(ParentClass, function (childInitVar) {
    this._childInitVar = childInitVar;
});

function extend (sup, base) {
    var descriptor = Object.getOwnPropertyDescriptor(base.prototype, "constructor");
    base.prototype = Object.create(sup.prototype);
    var handler={
        construct: function (target, args) {
            var obj = Object.create(base.prototype);
            this.apply(target, obj, args);
            return obj;
        },
        apply: function (target, that, args) {
            sup.apply(that, args);
            base.apply(that, args);
        }
    };
    var proxy = new Proxy(base, handler);
    descriptor.value = proxy;
    Object.defineProperty(base.prototype, "constructor", descriptor);
    return proxy;
}

Комментариев нет:

Отправить комментарий