ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript の値が値によって渡されるか、reference_javascript スキルによって渡されるかについてのディスカッション

JavaScript の値が値によって渡されるか、reference_javascript スキルによって渡されるかについてのディスカッション

WBOY
WBOYオリジナル
2016-05-16 16:16:491130ブラウズ

最近、「JS の値は値で渡されるのか、それとも参照で渡されるのか?」という興味深い質問に遭遇しました。

この問題を分析する前に、値による呼び出しと参照による呼び出しとは何かを理解する必要があります。コンピュータサイエンスでは、この部分は評価戦略と呼ばれます。関数を呼び出すときに、変数間、および実パラメータと仮パラメータの間で値がどのように渡されるかを決定します。

値渡し VS. 参照渡し

値による呼び出しは、最も一般的に使用される評価戦略です。関数の仮パラメータは、呼び出し時に渡される実際のパラメータのコピーです。仮パラメータの値を変更しても、実際のパラメータには影響しません。

参照渡し (参照呼び出し) の場合、関数の仮パラメータはコピーではなく実際のパラメータへの暗黙的な参照を受け取ります。これは、関数パラメータの値が変更されると、実際のパラメータも変更されることを意味します。同時に、両方とも同じ値を指します。

参照渡しでは、関数呼び出しのトレースがより困難になり、場合によっては微妙なバグが発生することがあります。

値渡しでは毎回クローンが必要となるため、一部の複雑な型ではパフォーマンスが低下します。値を渡すどちらの方法にも独自の問題があります。

まず、値渡しと参照渡しの違いを理解するために C の例を見てみましょう:

コードをコピー コードは次のとおりです:

void Modify(int p, int * q)
{
p = 27; // 値渡し – p は実際のパラメータ a のコピーであり、p のみが変更されます
*q = 27; // q は b への参照であり、q と b は両方とも変更されます
}
int main()
{
int a = 1;
int b = 1;
Modify(a, &b); // a は値によって渡され、b は参照によって渡されます、
// a は変更されていませんが、b は変更されています
Return(0);
}

ここで次のことがわかります:

a => p が値によって渡される場合、仮パラメータ p の値を変更しても、a の単なるコピーである実際のパラメータ a には影響しません。
b => q は参照によって渡されます。仮パラメータ q の値を変更すると、実パラメータ b の値にも影響します。
JS 値がどのように渡されるかを調べてください
JS の基本的な型は値によって渡されます。

コードをコピー コードは次のとおりです:

var a = 1;
関数 foo(x) {
x = 2;
}
foo(a);
console.log(a); // 1 のままですが、x = 2 の代入の影響を受けません

オブジェクトをもう一度見てみましょう:
コードをコピー コードは次のとおりです:

var obj = {x : 1};
関数 foo(o) {
o.x = 3;
}
foo(obj);
console.log(obj.x); // 3、変更されました!

o と obj は同じオブジェクトであり、o は obj のコピーではないことを説明します。したがって、値によっては渡されません。 しかし、これは JS オブジェクトが参照によって渡されることを意味するのでしょうか?次の例を見てみましょう:
コードをコピー コードは次のとおりです:

var obj = {x : 1};
関数 foo(o) {
o = 100;
}
foo(obj);
console.log(obj.x); // 1 のまま、obj は 100 に変更されていません。

参照によって渡される場合、仮パラメータ o の値を変更すると、実際のパラメータに影響を与えるはずです。ただし、ここで o の値を変更しても、obj には影響しません。 したがって、JS 内のオブジェクトは参照によって渡されません。では、JS でオブジェクトの値はどのように転送されるのでしょうか?

共有による通話

正確に言うと、JS の基本型は値渡しであり、オブジェクト型は共有渡しです (共有呼び出し、オブジェクト渡し、オブジェクト共有渡しとも呼ばれます)。これは、1974 年に Barbara Liskov によって GLU 言語で初めて提案されました。この評価戦略は、Python、Java、Ruby、JS およびその他の言語で使用されます。

この戦略の重要な点は、関数を呼び出してパラメータを渡すとき、関数はオブジェクト引数参照のコピー (値によって渡されるオブジェクトのコピーでも、参照によって渡される暗黙的な参照でもありません) を受け入れることです。 参照渡しとの違いは、共有転送での関数パラメータの割り当てが実際のパラメータの値に影響を与えないことです。次の例のように、仮パラメータ o の値を変更することによって obj の値を変更することはできません。

コードをコピー コードは次のとおりです:

var obj = {x : 1};
関数 foo(o) {
o = 100;
}
foo(obj);
console.log(obj.x); // 1 のまま、obj は 100 に変更されていません。

ただし、参照はコピーですが、参照されるオブジェクトは同じです。これらは同じオブジェクトを共有するため、仮パラメータ オブジェクトのプロパティ値を変更すると、実際のパラメータのプロパティ値にも影響します。
コードをコピー コードは次のとおりです:

var obj = {x : 1};
関数 foo(o) {
o.x = 3;
}
foo(obj);
console.log(obj.x); // 3、変更されました!

オブジェクト タイプの場合、オブジェクトは変更可能であるため、オブジェクト自体を変更すると、オブジェクトを共有する参照および参照コピーに影響します。基本型については、すべて不変であるため、共有渡しと値渡し(値呼び出し)に違いはありません。そのため、JS の基本型は値渡しと共有渡しの両方に準拠します。
コードをコピー コードは次のとおりです:

var a = 1; // 1 は数値型、不変 var b = b = 6;

pass-by-share 評価戦略によれば、a と b は 2 つの異なる参照 (b は a の参照コピー) ですが、同じ値を参照します。ここでの基本型 1 は不変であるため、値による受け渡しと共有による受け渡しに違いはありません。

基本型の不変の性質

基本型は不変(immutable)で、オブジェクトのみが可変(mutable)です。たとえば、数値100、ブール値true、false、これらの値を変更します(たとえば、1を3に変更します)。 true to 100 ) は意味がありません。誤解しやすいのはJSの文字列です。文字列の内容を「変更」しようとする場合がありますが、JS では、文字列値を「変更」するように見える操作は実際には新しい文字列値を作成します。

コードをコピー コードは次のとおりです:

var str = "abc";
str[0] // "a"
; str[0] = “d”;
str; // "abc" の代入はまだ無効です。文字列
の内容を変更する方法はありません。

しかし、オブジェクトは異なり、オブジェクトは変更可能です。
コードをコピー コードは次のとおりです:

var obj = {x : 1};
obj.x = 100;
var o = obj;
o.x = 1;
obj.x; // 1、変更されました
o = true;
obj.x; // 1、o = true
のため変更されません

ここでは変数 obj を定義し、その値は object で、obj.x 属性の値を 100 に設定します。次に、別の変数 o を定義します。その値は依然としてオブジェクト object です。この時点では、2 つの変数 obj と o の値は同じオブジェクトを指します (同じオブジェクトへの参照を共有します)。したがって、オブジェクトの内容を変更すると、obj と o の両方に影響します。ただし、オブジェクトは参照によって渡されません。o の値は o = true によって変更されます。これは obj には影響しません。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。