Невозможно получить базовый тип объекта - PullRequest
2 голосов
/ 28 октября 2019

Я пытаюсь получить базовый тип объекта, но не получается. Консоль Chrome, кажется, в состоянии это сделать, но я не могу.

Вот что дает мне консоль:

enter image description here

Я пытаюсь получить Blockly.FieldDropdown как-то.

Как консоль Chrome может это выяснить, но я не могу?

Объект возвращен Google Blockly:

var block = Blockly.mainWorkspace.getBlockById(e.blockId);
var field = block.getField(inputId); //field is the object shown in console above...

Или как отдельный рабочий пример:

var field = new Blockly.FieldDropdown([['left', 'LEFT'], ['right', 'RIGHT']]);
// these return an empty string, but I'd like to get back "Blockly.FieldDropdown"
console.log(Object.getPrototypeOf(field).constructor.name);
console.log(field.__proto__.constructor.name);
// the following shows "Blockly.FieldDropdown" in front of the properties
// in Chrome's dev console (but not in Firefox for example,
// and the name is not accessible):
// console.log(field);
<script src="https://cdn.jsdelivr.net/npm/blockly@3.20191014.3/blockly.min.js"></script>

Я пытался найти метод Blockly, который возвращает тип, но я его не видел.

1 Ответ

0 голосов
/ 29 октября 2019

Вот что я придумал. Он работает, перебирая свойства объекта Blockly и проверяя, является ли свойство инстанцируемым, а объект, который мы проверяем, является его прямым экземпляром.

Это очень специализированное решение, которое работает дляединый класс и его прямые свойства. Более общее решение должно было бы рекурсивно перебирать объект window (или globalThis, если не в контексте браузера), который был бы очень ресурсоемким (мог бы заморозить браузер) и включал бы механизм для предотвращения Too much recurson ошибок. Кроме того, при более глубокой вложенности могут возникнуть проблемы, различающие экземпляры и вложенные экземпляры из-за наследования. Этот ответ дает подсказку по этому вопросу.

Причины, по которым все это невозможно сделать с помощью тривиального встроенного решения, были изложены в этом связанном ответе .

var field = new Blockly.Field();
var fieldD = new Blockly.FieldDropdown([['left', 'LEFT'], ['right', 'RIGHT']]);
var fieldI = new Blockly.FieldImage('https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png', 1200, 286);

function getBaseType(o) {
  let baseType = null;
  Object.entries(Blockly).find(([name, t]) => {
    let isInstanceOf = t && t.prototype && Object.getPrototypeOf(o) === t.prototype;
    if (isInstanceOf) {
      baseType = `Blockly.${name}`;
    }
    return isInstanceOf;
  });
  return baseType;
}

console.log(getBaseType(field));
console.log(getBaseType(fieldD));
console.log(getBaseType(fieldI));
<script src="https://cdn.jsdelivr.net/npm/blockly@3.20191014.3/blockly.min.js"></script>
...