Любой способ определить ВСЕ переменные в функции как свойство этого?

Я знаю, это может показаться немного абсурдным, но я ищу способ определить каждую переменную внутри функции как свойство this. Я ищу любой хак, чтобы иметь возможность отслеживать переменные внутри функции (т.е. Добавлять их к объекту this), не имея на самом деле предисловия каждого определения переменной с помощью this.. Есть ли способ? Возможно ли это с помощью Proxy?

function () {
  // declare a variable
  var hello = 'hi'
  return this
}

let {hello} = function()
console.log(hello) // hi

Например, это работает:

function hi () { this.hello = true; return this }
hi.bind({})() // { hello: true }

Я хочу, чтобы все переменные, определенные в hi, добавлялись к объекту this, когда они определены.

Ответ 1

Вы ищете худший взломать воображаемый? Конечно, все возможно:

function example () {
  with(horrible(this)) {
    var hello = 'hi';
  }
}
var x = new example;
x.hello; // 'hi'


function horrible(target) {
  return new Proxy(target, {
    has() { return true; }, // contains all variables you could ever wish for!
    get(_, k) { return k in target ? target[k] : (1,eval)(k) }
  });
}

Прокси утверждает, что содержит все имена, которые могут когда-либо использоваться в качестве переменной в области with. Это в основном приводит ко всем присваиваниям необъявленных или var -declared переменных, создающих свойства на целевом объекте (если вы не используете let или const, они будут по-настоящему локальны для области блоков).
Тем не менее, для поиска переменных все, что не является целевым свойством, будет разрешено в глобальной области (с использованием глобального eval), поскольку исходная область не может быть сохранена, когда прокси заявляет, что может передавать все переменные.

Ответ 2

Вы можете, вроде. Но это очень грязный хак, который требует от вас

  • Оберните код внутри оператора with, который имеет затраты на производительность, является плохой практикой и не разрешен в строгом режиме.
  • Используйте зла eval, чтобы получить значения переменных.
  • Могут быть ложные срабатывания. Обнаружены только переменные var, но не let или const.

function func() {
  // The proxy will detect the variables
  var vars = [];
  var proxy = new Proxy({}, {
    has(target, property) {
      vars.push(property);
    }
  });
  with(proxy) {
    // Place your code here
    var hello = 'hi';
  }
  // Assign the variables as properties
  for (var property of vars)
    this[property] = eval(property);
  return this;
}
let {hello} = func.call({});
console.log(hello) // hi