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-combinatorの紹介

4

3 に答える 3

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 に答える
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 に答える
0

thisここでキーワードを使用できます。

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

oそれははるかに簡単なアプローチです...実際、あなたがそれを参照するときに定義されていないように、あなたのアプローチは不可能ですらありません。

于 2010-12-15T20:16:52.707 に答える