Могу ли я использовать Y-комбинатор, чтобы получить ссылку на объект для этого замыкания? - PullRequest
2 голосов
/ 15 декабря 2010

это замыкание работает:

var o = {
    foo: 5
};

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

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

возможно ли определить встроенный обработчик, возможно, с чем-то похожим на операцию y-комбинатора?

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

из академического любопытстваЯ не пытаюсь сделать это в рабочем коде

введении в y-комбинатор

Ответы [ 3 ]

1 голос
/ 15 декабря 2010

Это невозможно с литералом объекта отдельно , как указывали другие.Тем не менее, процесс может быть завернут.Является или нет это "добавляет что-нибудь" является спорным.Это не то же самое, что 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, если таковые имеются - упражнение для читателя.

Удачное кодирование.

1 голос
/ 15 декабря 2010

Нет, это невозможно, поскольку во время определения литерала объекта переменная o не определена, а ссылка this во время определения не ссылается на o.

Если бы вы использовали временную ссылку на this во внешней функции и передали ее в замыкание, это сработало бы, но вы не смогли бы передать объект, чтобы получить свойство foo из.

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

var h = o.handler();
h();
0 голосов
/ 15 декабря 2010

Вы можете просто использовать ключевое слово this здесь:

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

Это гораздо более простой подход ... На самом деле, ваш подход даже невозможен, так как o не определяется, когда выобратитесь к нему.

...