Наследование прототипов JavaScript: сжатый синтаксис? - PullRequest
0 голосов
/ 22 декабря 2011

Есть ли более краткий способ выразить это, чем три отдельные процедурные операции? Что-то более похожее на обозначение объекта или, по крайней мере, все в теле функции Name?

Проблема:

function Name(first, last) {
    this.first = first;
    this.last = last;
}

Name.prototype = new String;

Name.prototype.toString = function() {
   return this.last + ', ' + this.first;
};

Тест:

console.log(new Name("jimmy", "dean").toString())
console.log(new Name() instanceof Name);
console.log(new Name() instanceof String);
console.log(new Name() instanceof Object);
console.log(Name.prototype.toString.call(new Name('jimmy', 'dean')));
console.log(Name.prototype.toString.call({
    first: 'jimmy',
    last: 'dean'
}));

Ожидаемый результат:

< "dean, jimmy"
< true
< true
< true
< "dean, jimmy"
< "dean, jimmy"

Ответы [ 3 ]

1 голос
/ 22 декабря 2011

Пример

function Name(first, last) {
    this.partFirst = first;
    this.partLast = last;
    this.valueOf = this.toString = function() {
        return this.partLast + ', ' + this.partFirst;
    }
}
Name.prototype = new String();
0 голосов
/ 22 декабря 2011

Вот как я это делаю:

function subclass(constructor, superConstructor) {
    function surrogateConstructor() { }

    surrogateConstructor.prototype = superConstructor.prototype;

    var prototypeObject = new surrogateConstructor();
    prototypeObject.constructor = constructor;

    constructor.prototype = prototypeObject;
}



/* Base object */
function BaseItem() {
    this.type = 'baseitem';
    this.obj = null;
}
BaseItem.prototype.render = function() {
    return "foo";
}



/* Sub class */
function InteractionArea() {
    BaseItem.call(this);
    this.type = 'interactionarea'
    this.obj = document.createElement('div')
}
subclass(InteractionArea, BaseItem);

//here come the overrides
InteractionArea.prototype.render = function() {
    return "foobar";
}
InteractionArea.prototype.render2 = function() {
    return "foobar";
}



/* Sub-sub class */
function InteractionArea2() {
    InteractionArea.call(this);
    this.type = 'interactionarea2';
    this.obj = false;
}
subclass(InteractionArea2, InteractionArea);

InteractionArea2.prototype.render = function() {
    return "bar";
}
0 голосов
/ 22 декабря 2011

Конечно. Используйте Object.create.

var Name = Object.create(String.prototype, {
  toString: { value: function _toString() {
    return this.partLast + ', ' + this.partFirst;
  } },
  constructor: { value: function _constructor(first, last) {
    this.partFirst = first;
    this.partLast = last;
    return this;
  } }
});

var name = Object.create(Name).constructor("foo", "bar");

Теперь ES5 немного уродлив, поэтому вы можете использовать некоторый механизм для ES5 OO сахара , давайте возьмем pd в качестве примера:

var Name = pd.make(String.prototype, {
  toString: function _toString() {
    return this.partLast + ', ' + this.partFirst;
  },
  constructor: function (first, last) {
    this.partFirst = first;
    this.partLast = last;
  },
  beget: pd.Base.beget 
});

console.log(Name.beget("jimmy", "dean").toString())
console.log(Name.isPrototypeOf(Name.beget()));
console.log(String.prototype.isPrototypeOf(Name.beget()));
console.log(Object.prototype.isPrototypeOf(Name.beget()));
console.log(Name.toString.call(Name.beget('jimmy', 'dean')));
console.log(Name.toString.call({
    partFirst: 'jimmy',
    partLast: 'dean'
}));

Конечно, результат получился, как и ожидалось Живой пример

...