1

別のスレッドで、関数が終了した後、関数内からオペランドに加えられた変更はすべて保持されると言われました。私はいつも、渡されたすべての値の一時的なコピーを作成すると思っていました。その後、永続化されたのは、戻り値と、変更された暗黙的により広いスコープの変数だけでした。

私がピークに達したソースコードを持つすべてのjqueryプラグインを振り返ると、それらはすべて構成を使用していると思います。

(function($){
  $.fn.foo = function(){ console.log('foo'); };
})(jQuery);

jQueryこれは、内部スコープ識別子によるオブジェクトへの変更が関数の終了後も持続することを意味し$ます。そうしないと、jQueryプラグインが機能しません。したがって、これは上記のスニペットと同じように機能します。

var x = {n:0};

(function addOneTo(p) {
  p.n = p.n + 1;
})(x);

console.log(x);

でも、これ:

var x = 0;

(function addOneTo(p) {
  p = p + 1;
})(x);

console.log(x);

xそうではなく、値を変更せずに残します0

誰かが引数の受け渡しがどのように機能するかを説明できますか?私はそれがどのように行われるかを知っていると思いましたが、私は知らないと思います。ありがとう

4

3 に答える 3

1

あなたが持っているとき:

p.n = p.n + 1;

あなたがしているのは、によって参照されるオブジェクトで呼び出されるプロパティを変更することです。つまり、オブジェクトへのポインタと見なすことができます。つまり、関数に渡した参照値を持つ元のオブジェクトへの参照を保持します。一方、あなたが持っているとき:npp

p = p + 1;

によって保持されているオブジェクト参照値を、式を評価した結果に置き換えるだけです。オブジェクトのプロパティを変更していません。pp + 1p

于 2012-09-22T01:23:25.287 に答える
1

これは実際には非常に単純です。Javascriptのすべての名前は、メモリ内のオブジェクトを指します(オブジェクト指向の方法で考えていなくても)。これは、その「要素」のデータ構造が存在するメモリ内の位置です。

したがって、渡された値が配列などのオブジェクト、または属性と名前を持つ他の要素である場合、関数内で取得するのは同じオブジェクトです。p.n = p.n + 1「p」オブジェクトは関数の内部と外部で同じであるため、属性を変更すると(上記の例のように)。

ここで、次の操作を行うとp = p + 1、名前で参照されている元のオブジェクトpが、式で作成され、値が。の別のオブジェクトに置き換えられます p + 1。関数内の名前pは、別のメモリ位置にある別のオブジェクトを完全に指し、元のオブジェクトは関数に渡され、名前を使用したオブジェクトからの参照は変更xされません。

このメカニズムは、たとえばPython言語で発生するメカニズムとまったく同じです。

于 2012-09-22T01:29:54.407 に答える
1

実際、最初の例では

var x = {n:0};
(function addOneTo(p) {
    p.n = p.n + 1;
})(x);
console.log(x);

これxはオブジェクトであり、使用p.n = p.n + 1;すると元のオブジェクトのプロパティが変更されました。これは、参照として渡されたためです(pはxと同じオブジェクトです)が、2番目の例では

var x = 0;
(function addOneTo(p) {
    p = p + 1;
})(x);
console.log(x);

xは関数に値によって渡され、p = p + 1;ここpにその関数内の新しいプライベート変数があり、関数スコープのみがあります。

于 2012-09-22T01:35:33.417 に答える