【问题标题】:Any way to define ALL variables within function as property of this?有什么方法可以将函数中的所有变量定义为 this 的属性?
【发布时间】:2016-12-08 22:21:02
【问题描述】:

我知道这可能听起来有点荒谬,但我正在寻找一种方法来将函数中的每个变量定义为this 的属性。我正在寻找任何 hack,任何可能的方式来跟踪函数中的变量(即将它们添加到 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 对象的方法。

【问题讨论】:

  • this 不是一个奇异的本性吗?对函数所有者的引用?任何变量都可以引用this,但它只引用一件事。可以通过.call.apply更改。
  • 你不能那样做。

标签: javascript 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 变量的分配在目标上创建属性(除非您使用letconst,它们将真正位于块范围内)。
但是,对于变量查找,所有不是目标属性的内容都将在全局范围内解析(使用全局 eval),因为当代理表示它可以传递所有变量时,无法保留原始范围。

【讨论】:

  • 比我的回答要干净得多!但是对外部变量的引用不起作用,例如console.log('foo')
  • @Oriol 我只是在解决这个问题:-)
  • @Bergi 以任何方式包含用letconst 声明的变量?
  • @ThomasReggi 不,但如果您需要一些不应成为属性的变量,这实际上非常有用。如果您真的想要完全控制,请获取函数的代码(通过.toString)并进行静态分析或编译。
【解决方案2】:

你可以,有点。但这是一个非常肮脏的 hack,需要你这样做

  • 将代码包装在with 语句中,这会降低性能,是不好的做法,并且在严格模式下是不允许的。
  • 使用 evil eval 获取变量的值。
  • 可能存在误报。仅检测到 var 变量,但未检测到 letconst 变量。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 2017-05-16
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2017-10-23
    相关资源
    最近更新 更多