2

这个关闭有效:

var o = {
    foo: 5
};

o.handler = function(obj){
    return function() {
        alert(obj.foo);
    };
}(o);

o.handler(); //alert('5')

是否可以在线定义处理程序,也许使用类似于 y-combinator 操作的东西?

var o = {
    foo: 5,
    handler: function(obj){
        return function() {
            alert(obj.foo);
        };
    }(o); //pointer to o? -----------------------------
};

出于学术好奇心,我不想在生产代码中这样做

y 组合器简介

4

3 回答 3

1

正如其他人所指出的,这对于对象文字本身是不可能的。但是,可以包装该过程。它是否“增加了任何东西”是有争议的。这与 Y-Combinator 不同(可能是一半?),因为它不是试图给出“递归名称”(据我所知,Y-Combinator 假设一等函数和闭包或一个模拟这样的方法)。

function bindMany (dict, res) {
  res = res || {}
  for (var k in dict) {
    if (dict.hasOwnProperty(k)) {
      var v = dict[p]
      res[k] = v instanceof Function ? v(res) : v
    }
  }
  return res
}

var o = bindMany({
  foo: 5,
  handler: function(obj){
    return function() {
      alert(obj.foo)
    }
  }
})

未经测试,但显示了可以采取的方法。dict这和/上的原型链有一些微妙的问题res,如果有的话 - 读者练习。

快乐编码。

于 2010-12-15T20:39:43.803 回答
1

不,这是不可能的,因为在定义对象字面量时,变量o是未定义的,并且在this定义时的引用没有引用o

如果您在外部函数中使用临时引用this并将其传递给闭包,它会起作用,但您将无法传入对象以从中foo取出属性。

var o = {
    foo: 5,
    handler:function(){
        var self = this;
        return function() {
            alert(self.foo);
        };
    }
};

var h = o.handler();
h();
于 2010-12-15T20:15:30.720 回答
0

你可以在this这里使用关键字:

var o = {
    foo: 5,
    handler: function() {
      alert(this.foo);
    }
};

这是一个更简单的方法......实际上,您的方法甚至是不可能的,因为o在您引用它时没有定义。

于 2010-12-15T20:16:52.707 回答