「Call by value」と「Call by reference」(フィート.JavaScript)



「Call by value」と「Call by reference」とは?

call by valuecall by referenceは、変数やオブジェクトなどから関数に入るパラメータ(パラメータ)であり、パラメータ(パラメータ)に渡すときにどのように渡すかを決定する.
関数を呼び出すには、次の2つの方法があります.
  • 値による呼び出し(値による呼び出し、値による複製)
  • 呼by reference(参照呼によりアドレスをコピー)
  • 参照モード


    通常、基本型(オリジナル型)をパラメータとして渡すと、値で渡されます.
    参照型をパラメータとして渡す場合はCallbyReference方式で渡す.
    基本(オリジナル):数値、文字列、ブール値、null、undefiend、構成部品
    参照:オブジェクト、配列、関数、日付、正規表現

    parameter, argument


    パラメータ(パラメータ)は、関数を呼び出すときに渡される値を表します.
    パラメータ(parameter)は、渡された値を受け入れる変数を表します.
    function sum(a, b) {	// a, b는 매개변수(parameter)
      return a + b;
    }
    sum(10, 20);	// 10, 20은 인자(argument)

    Call by value(値呼び出しで値をコピー)


    値のコピー(Call by value,値のコピー)は、コピーした値をパラメータに渡します.
    基本タイプ(Primitive type)では、callby valueで渡されます.
    利点:コピー処理が安全です.原価保留
  • の欠点:レプリケーションによりメモリ使用量が増加します.
  • コールリファレンス(リファレンス呼び出しによるアドレスのコピー)


    callbyreference(アドレス値のコピー)は、実際のデータが存在するアドレスを指すアドレス値をパラメータに渡します.
    オブジェクト(ex.obj、array、function...)callby referenceで渡します.
  • の利点:コピーする必要がなく、直接参照できます.
  • 欠点:直接参照は元の値に影響します.(リスク)

    JavaScriptは?


  • 元のタイプの場合、callby valueを使用して操作します.

  • 参照タイプについてはcallbyreferenceとして操作します.
  • JavaScriptがどのタイプの資料型(基本型、参照型)であるかにかかわらず、callby valueは常に使用されます.
    参照タイプが余分であっても、参照タイプのアドレス値がコピーされ、パラメータとして渡されます.

    function foo(obj2) {
      obj2= 10;
      console.log(obj2);	// 10
    }
    let obj1 = { a: 5, b: 8 };
    foo(obj1);
    
    console.log(obj1);	// { a: 5, b: 8 }

    C++言語で?


    ポインタとcall by referenceの概念を持つC、C++言語では、2行目のobj2 = 10;obj1の値を10に変更します.完全なアドレス値参照に接続されているためです.

    JavaScriptでは?


    ただし、JSの場合、オブジェクト自体(オブジェクトのプロパティ値ではなく)の変更は許可されません.表面的にはアドレス値を参照しているため、実際にはアドレス値のコピーを作成して転送します.

    アクションの説明



    まず、foo(obj1);obj1が関数foo()のパラメータに変換されると、obj2に示されるアドレス値と同じobj1が複製され、伝達される.

    そして、関数内部のobj2からobj2 = 10;を格納するアドレス値に変更する.

    練習する。


    case1

    const f1 = obj => {
      obj = null;
    }
    
    let b1 = {'a': 1};
    f1(b1);
    console.log(b1); // { a: 1 }
    b 1はオブジェクトをnullにするようですが、できません.
    objには株価のコピーが含まれます.
    私たちが望むb 1株価に値を割り当てるのではなく、別の株価にnullを割り当てるのです.

    case2

    const f2 = array => {
      array = null;
    }
    
    let b2 = [];
    let a2 = b2;
    f2(b2);
    console.log(b2); // []
    配列もcase 1と同じです.

    case3

    const swap = (a, b) => {
      let tmp = a;
      a = b;
      b = tmp
    }
    
    let x = 1;
    let y = 2;
    
    swap(x, y);
    console.log(x, y); // 1, 2
    基本型を超えるのも馬車枝です.交換は発生しません.

    case4


    const f = (a) => { a = 2; } let b = 11; f(b); console.log(b); // 11 case 3に似ています。コピーアドレスを持つ変数で値が変更されたため、出力は11となる。

    case5

    const a = { 'a': 1 };
    const b = (c) => {
      c.a = 2;
    } 
    b(a);
    console.log(a) // { a: 2 }
    オブジェクトのプロパティが変わります.
    参照型のコピーネイティブオブジェクトが渡されるため、オブジェクトは異なるポップアップ値を持つが、両方のオブジェクトの値は同じobj2である.
    この状態で,cの属性が変化すると,同じ値を望むaの属性も変化する.

    case6

    const foo = (b) => {
      b = b.a = 1;
      b.b = 2;
    };
    
    const a = {};
    foo(a);
    console.log(a); // { a: 1 }
    2行目10を見てください.
    複数の付与演算子が接続されている場合、評価は右側から開始されます.( 注意-自動配賦演算子 ){ 'a' : 1 }のため、変数aが指す値はb = b.a = 1;に割り当てられる.
    それからbに1を割り当てます.
    3行目b.a = 1は基本型として指定されているので無視される.
    従って、結果aは{ a: 1 }であった.