2016-05-10 2 views
1

私はJavaScriptの初心者です。私は入れ子関数を回避する方法を見つけようとしていました。さて値yを維持し、その機能apple()setTimeoutフォームの閉鎖以来、コンソールに印刷し、それがうまく機能している以下の2例閉鎖なしで非同期呼び出しで変数を使用できるようにする

// example 1 
var x = 45; 
function apple(){ 
    var y = 60; 
    setTimeout(function(){ 
     console.log(y); 
     console.log(x); 
    }, 20); 
} 
apple(); 
console.log(x); 

を見てみましょう。今、私はrun()を機能させる機能利用可能apple()の変数を作るのですかどのように私は別に関数本体を配置したかった

var x = 45; 
var run = function(){ 
     console.log(y); 
     console.log(x); 
}; 
function apple(){ 
    var y = 60; 
    setTimeout(run, 20); 
} 
apple(); 
console.log(x); 

コードの下を見て、引数として関数ハンドラを渡すが、私は立ち往生午前事があります彼らはもはや閉鎖を形成しないからです。それを可能にする回避策はありますか?親切に私を助けてください。

一般的な方法で私に答えると、nodejs APIにも適用されます。私はsetTimeoutがより多くの議論を受け入れるのを見てきましたが、関数プロトタイプとは無関係に解決策を適用したいと思っています。

更新

申し訳ありませんが、私はすべての答えは、値渡しを使用して関数呼び出しを行うと思います。その閉鎖を達成していない。彼らは、現在のy値をとり、関数の引数として渡し、これはY = 60としない80 run()内部を印刷

var y = 60; 
setTimeout(run, 20); 
y = 80; 

コードの下等setTimeout()y = 80の文が存在すると仮定する。私は実際にyの参照を維持し、クロージャのようにその値をキャプチャしないことを望みます。あなたは

答えて

2

あなたはbindを使用することができ感謝:バインドのための

var x = 45; 
var run = function(y){ 
     console.log(y); 
     console.log(x); 
}; 
function apple(){ 
    var y = 60; 
    setTimeout(run.bind(null, y), 20); 
} 
apple(); 
console.log(x); 

最初の引数はあなたがthisにバインドしたいと思うものです。その後、それぞれの引数が新しく作成された関数に渡されます - run関数の引数としてyを追加したことに注意してください。

あなたに与えられるものは、あらかじめ定義されたコンテキスト(this)とおそらく引数のデフォルト値を持つ新しい関数です。

ただし、このようなシナリオは常に避けるべきです。関数内の外部変数を変更することは決して良い考えではありません。それは早すぎる悲しみや灰色になるでしょう。参照やグローバルスコープの変数に依存せず、値を渡したり返すことができるように、コードをリファクタリングするようにしてください。

+0

申し訳ありませんが、私は上記のコードが参考になると思います。それは実際に価値によって捕捉されます。たとえば、setTimeout文の後にy = 80があるとします。 setTimeoutハンドラは、80ではなく60を出力します。 – user3205479

+0

この解決策はクロージャのようには機能しません。更新された質問をご覧くださいありがとうございました – user3205479

+1

@ user3205479プリミティブ値は常に値によって渡されます。あなたが求めていることは不可能です。 – Schlaus

0

変数はrun()のスコープにありませんので、runに渡す必要があります。また、あなたはYとあなたがX(グローバルとして設定)で行うのと同じ操作を行うことができapple(cb_fn)https://jsfiddle.net/stevenkaspar/ttxxpoof/

var x = 45; 
var y = 80; 
var run = function(){ 
    console.log('could be 80 or 85(depending on race condition): ' + y); 
    console.log('should be 45: ' + x); 
}; 

function apple(cb_fn){ 
    var y = 60; // you can declar var y again to have another ignore global y 
    setTimeout(function(){ 
    console.log('should be 60: ' + y); 
    cb_fn(); // this would be a callback function 
    }, 20); 
} 

apple(run); // you need to pass run in as a "callback" function 
console.log('should be 45: ' + x); 
y = 85; 
console.log('should be 85: ' + y); 
+0

私の更新された質問を参照してくださいありがとう – user3205479

+0

あなたは良い考えではない競合状態を設定しているようです。私はコードを更新しましたが –

0

にパラメータとして実行渡すことができます。

+0

私の更新された質問をご覧くださいありがとう – user3205479

+0

申し訳ありませんが、それが表示されます60 – user3205479

+0

変数 "y"をグローバルにしました。もしグローバル変数を作成することに興味がないのですが、リンゴが100の変数を持っていれば、すべての変数をグローバルにする必要がありますか? – user3205479

関連する問題