LINUX.ORG.RU

JavaScript прототипирование и this


0

1
function Proto() {
  this.getter;
  this._get = function() {
    return this.getter();
  }
  this.child = {};
  Object.defineProperty(this, "get", {
    enumerable: true,
    get: this._get
  });
  Object.defineProperty(this.child, "get", {
    enumerable: true,
    get: this._get
  });
}
function Sub() {
  this.getter = function() {
    return "ok";
  }
}
Sub.prototype = new Proto();
var s = new Sub();
s.get; //тут все выполняется
s.child.get; //тут ошибка this.getter undefined, что очевидно

В коде в последних строчках видно что появляется ошибка при доступе к свойству, в принципе нетрудно догадаться о причинах - this не указывает на нужный объект, однако применение

var thiz = this;

тут не поможет ибо thiz будет указывать на прототип, а не на Sub-объект, соотвественно getter`а тажке не будет.

Как быть?

Deleted

Беги! Беги!

You cannot hide forever!

anonymous
()

Нужно это для ORM-подобного фреймворка где результат сложного запроса выгружается в виде карты имяКолонки->индексКолонки и двумерного массива с данными. имяКолонки - может раделятся точкой, тогда перед нами вложенный объект:

colToIndex = {
  obj.id: 0
  obj.name: 1 
  obj.type.id:2
  obj.type.name:3
}
data =  [
  [0, "one",   0, "string"],
  [1, "two",    1, "int"],
  [2, "three", 0, "string"],
]

// скрипт генерит массив объектов вида:

{
  id:0,
  name: "one",
  type: {id:0, name:"string"}
}

есесно чтобы не генерить объект для каждой строки (а их дофига) то генерится прототип с геттерами, а для каждой строки лениво создается объект с индексом строки и данным прототипом, но вот косяк для вложенности > 0 случается описанный в топике облом.

Deleted
()

Выслать группу лексического захвата!

//упорот-кун

Sphinx ★★☆☆
()

Ну и кто тут говорил, что прототипирование лучше нормального ООП? Борьба нанайских мальчиков какая-то.

anonymous
()
Ответ на: комментарий от anonymous

в данном случае мне видится проблема конкретной реализации прототипирования, а не парадигмы 8)

Deleted
()
Ответ на: комментарий от Deleted

Не понял какой getter будет undefined.

function Sub() {
  this.getter = function() {
    return "ok";
  }
  this.child.getter = this.getter
}

У меня твой пример заработал.

Chumka ★★★
()
Ответ на: комментарий от Deleted

структура прототипа в Sub неизвестна.

сколько же ограничений...

тогда только так где-то:

this._get = function() {
    return this.getter === undefined ? this._parent.getter() : this.getter();
  }

...

s.child._parent = s

Chumka ★★★
()
Ответ на: комментарий от Deleted

_parent будет указывать на предка child, то есть на s.

s - это объект, производный от Sub(), в котором есть нужный метод

Chumka ★★★
()
Ответ на: комментарий от Chumka

попросту говоря вы предлагаете в конструкторе Sub пробежаться по свойствам объекта взятым от протитпа и присвоить им _parent?

Deleted
()
Ответ на: комментарий от Deleted

так тоже заработает, но это уж совсем криво. я предлагал присваивать _parent НЕ в конструкторе, а в коде. После создания объекта:

s = new Sub()
s.child._parent = s
Chumka ★★★
()
Ответ на: комментарий от Chumka

тут непонятно что кривее, при том что структура как я и говорил не известна пользователю объекта - она генерится в прототипе конструктра

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.