2012-01-12 20 views
3

で「ゲッターを返す」ことは可能です:もちろんが、それは私がこのような何かやりたいのjavascript

function x(){ 
    var o = {}; 
    o.__defineGetter__('y', function(){ 
     return new Date(); 
    }); 

    return o.y; 
} 

var z = x(); 
console.log(z); 
//Wait 1 second 
console.log(z); //Date should be one second past the last printing 

を、それが返されたときo.yが評価されているので、これは動作しません。私はgetterとして動作する変数を返す方法を探しています。次の例は、このようなことが可能になることを期待しています。

function x(context){ 
    //Bind the getter to the passed in scope 
    context.__defineGetter__('y', function(){ 
     return new Date(); 
    }); 
} 

x(this); 
console.log(y); 
//Wait 1 second 
console.log(y); //Date is one second past last printing 

誰もこれまでこのようなことを試みたことはありますか?

はい、私は、異なる構文を使用して同様の動作をモデル化する他の方法に精通しています。私はこの特殊な構文が特別なシナリオのために働きたいだけです。

おかげで、

クリス

答えて

1
function x(){ 
    var o = function() {}; 
    o.__proto__ = { 
      valueOf: function() { 
       return new Date().toString(); 
      } 
    }; 

    return o; 
} 

var z = x(); 
console.log(z); // Tue Mar 13 2012 14:10:10 GMT+0200 (GTB Standard Time) 
setTimeout(function() { 
    console.log(z); // Tue Mar 13 2012 14:10:12 GMT+0200 (GTB Standard Time) 
}, 2000); 
+0

これは受け入れられる回答である必要があります。しかし、関数x()から "valueOf"プロパティを持つオブジェクトを返すほうが簡単です。 "function x(){return {valueOf:function(){...}};}" –

+0

はい、私はより多くの方法と簡単な方法で記述することができます。しかし、私はx()とその中のオブジェクト定義の理由は、oがより多くのメソッドとプロパティを持つことができ、それらはすべてxのプライベートコンテキストで定義されているということです。 x()は、出力されたときに(この例では)時間を表示するだけでなく、o.speak()などを持つこともできます。だから質問のために、答えは文脈を尊重する必要があります不完全または一見無益または間違っている。 – TheBrain

+0

合意。しかし、私が意図したことは、戻りたいオブジェクトとして関数を使用する理由はありませんでした。\ _ \ _ proto \ _ \ _にパッチのあるブラウザがサポートされています。元の質問は関数オブジェクトを返さないので、これは不必要なノイズを追加すると思います。 –

1

ここでの問題は、あなたが最初の関数でo.yを返しているとき、あなたはあなたが呼び出すことによって返されたDateオブジェクトを返している、getterメソッドを返していないということですgetterメソッドその場合、Dateオブジェクトをzに割り当てます。したがって、console.log(z)のたびに、そのDateオブジェクトをログに記録し、関数を再度呼び出さないでください。

2番目の例では、console.log(y)を実行すると、毎回その関数を実際に呼び出しています。

可能な解決方法は、あなたがやりたいことではないが、最初の例のゲッターに関数を返させることです。その後、それは動作します。彼らは私が混乱することができたと最後にいつもの()のない関数を呼び出すので、通常、あなたはo.y関数を返すのではなく呼び出しを期待したいので

function x(){ 
    var o = {}; 
    o.__defineGetter__('y', function(){ 
     return function() { 
      return new Date(); 
     } 
    }); 

    return o.y; 
} 

var z = x(); 

console.log(z()); 
//Wait 1 second 

setTimeout(function() { 
    console.log(z()); //Date is one second past last printing 
}, 1000) 

ゲッターメソッドは、JavaScriptで特殊なケースの一種であります機能。

+1

誰にでも下落した人に:あなたがそれを行うつもりなら、説明をしてください。あなたが間違っていることに気がついた場合は、コメントを残すほうがずっと役に立ちます。 –

+0

あなたの 'function x ...'は不正なコーディングスタイルを教えているので、 'var z = function(){return new Date()};'に置き換えてください。デモhttp://jsfiddle.net/vrtja/ – bennedich

+0

それは私のものではなくオリジナルのポスターからのコードでした。私は彼が書いたものをコピーし、いくつかの行を変更します。ダウン投票する前に注意してください。 –

2

答えはいいえです。変数のようにアクセスしたときの関数であるように、変数を動作させる変数に値を割り当てることはできません。あなたが質問で指摘したように、あなたが最も近づくことは、ゲッター関数を使ってプロパティを定義することです。記述したように機能する関数のローカル変数を作成することはできません。

ただし、ゲッター関数(グローバルオブジェクトのプロパティ)を使用してグローバルプロパティを定義し、必要としたように見えるようにする関数を定義できます。例として、ES5では次のようにグローバル変数yが作成されます。

function x(n) { 
    Object.defineProperty(this, n, { 
     get: function() { 
      return new Date(); 
     } 
    }); 
} 

x('y') 

注意:これは非完全モードでのみ機能します。 strictモードでは、thisの値はundefinedになります。

なぜあなたは私が推測することができないような行動をしたいのですか?

+0

@ nikc.orgありがとう!しかし、今では誰かが実際にそれを使用しようとしているようにうまくフォーマットされています。 Yikes! – chuckj

+0

できます。これをやってみてください。 var x = {valueOf:function(){console.log( "私は変数でなければなりません"); return Math.random()}}; console.log(10 * x); – TheBrain

+0

それは非常に賢いと近づく。ただし、与えられたケース、つまり "console.log(x);"では機能しません。パラメータとしてxを渡してもvalueOf()呼び出しは強制されないので、 "[object Object]"を出力します。しかし、まだまだクールです! – chuckj

関連する問題