Javascript의 가치 VS 참조

20520 단어 programmingjavascript

개요


  • Javascript에는 6가지 기본 데이터 유형이 있습니다. string , number , bigint , boolean , undefined , symbol . 하지만 null 동작 때문에 기본 데이터 유형으로 간주되지만 경우에 따라 null 처음 보이는 것처럼 "원시적"이 아닙니다! 모든 개체는 null 작성자 Prototypal Chain 따라서 typeof 연산자는 객체를 반환합니다.
  • 기본 데이터 유형은 값으로 복사됩니다.
  • Javascript는 또한 Object와 같은 또 다른 데이터 구조를 제공합니다. , 그 자체는 Array와 같은 기본이 아닌 다른 데이터 유형을 만드는 데 사용됩니다. , Function , Map , Set , WeakMap , WeakSet , Date .
  • 이러한 기본이 아닌 데이터 유형은 참조로 복사됩니다.

  • 기본 데이터 유형 예



    기본 데이터 유형을 복사하는 예를 들어 보겠습니다.
    여기서 값이 다른 변수에 그대로 복사되는 것을 볼 수 있습니다.

    let a1 = "Javascript";
    let b1 = 10;
    let a2 = a1;
    let b2 = b1;
    console.log(a1, b1, a2, b2); 
    // Javascript 10 Javascript 10
    


    이제 이전에 선언한 a2b2 a1 안에 저장된 값을 볼 수 있습니다. 및 b1 영향을 받지 않았습니다.

    let a1 = "Javascript";
    let b1 = 10;
    
    let a2 = a1;
    let b2 = b1;
    
    a2 = "Java";
    b2 = 20;
    console.log(a1, b1, a2, b2); 
    // Javascript 10 Java 20
    


    기본이 아닌 데이터 유형의 예



    이제 기본이 아닌 데이터 유형이 있고 이를 다른 변수에 복사한다고 가정합니다.

    let arr1 = ["1", "2", "3", "4"];
    let arr2 = arr1;
    console.log(arr1, arr2); 
    // ["1", "2", "3", "4"]
    // ["1", "2", "3", "4"]
    


    그러나 이제 arr2를 약간 변경하면 됩니다.

    arr2[2] = "5";
    console.log(arr1, arr2);
    // ["1", "2", "5", "4"]
    // ["1", "2", "5", "4"]
    


    복사된 배열 arr2 원래 배열 arr1에도 반영됩니다. . arr2 = arr1 즉, arr1 내부에 저장된 값의 참조를 arr2에 할당했습니다. 그리고 이것은 기본이 아닌 모든 데이터 유형의 경우입니다.

    예를 들어 배열과 같이 기본이 아닌 데이터 유형을 복사하려는 경우 수행할 수 있는 작업은 무엇입니까?

    let arr = ["1", "2", "3", "4"];
    // Option-1: Using Array.prototype.slice() method. [Shallow Copy]
    let arrCopy1 = arr.slice();
    // Option-2: Using Array.prototype.concat() method. [Shallow Copy]
    let arrCopy2 = [].concat(arr);
    // Option-3: Using es6 spread operator. [Shallow Copy]
    let arrCopy3 = [...arr];
    // Option-4: Using Array.from() method [Shallow Copy]
    let arrCopy4 = Array.from(arr);
    


    이제 이 새로 복사된 배열 내부에서 무엇이든 변경하면 arr 내부의 원래 값이 변경됩니다. 변경되지 않습니다.Objects의 단순 복사용 Object.assign() 사용

    let car = {"brand": "BMW", "wheels": 4};
    let bike = Object.assign({}, car, {"wheels":2, "safety":3});
    console.log(car, bike);
    // {brand: "BMW", wheels: 4} {brand: "BMW", wheels: 2, safety: 3}
    


    얕은 VS 깊은 복사(배열)



    그러나 여기서 기억해야 할 점은 이러한 모든 기술이 shallow copy deep copy 대신 , 즉 배열이 중첩되거나 다차원이거나 개체를 포함하는 경우 해당 배열 내부에서 무언가를 변경하면 작동하지 않습니다.
    예를 들어 설명하겠습니다.
    여기서 나는 Array.prototype.slice() 복사용이지만 다른 것도 사용할 수 있습니다.

    let obj1 = {"name":"shivaansh"};
    let obj2 = {"name":"agarwal"};
    let arr = [obj1, obj2];
    let arrCopy1 = arr.slice();
    arrCopy1[0].age = 22;
    console.log(arr, arrCopy1);
    /*
    [{"name":"shivaansh", "age":22}, {"name":"agarwal"}]
    [{"name":"shivaansh", "age":22}, {"name":"agarwal"}]
    */
    


    딥 카피의 경우 여기에서 볼 수 있듯이 위의 기술은 실패합니다.

    따라서 이를 피하기 위해 일부 개발자는 일반적으로 JSON 방법을 사용하는 것을 선호합니다.

    let obj1 = {"name":"shivaansh"};
    let obj2 = {"name":"agarwal"};
    let arr = [obj1, obj2];
    let arrCopy1 = JSON.parse(JSON.stringify(arr));
    arrCopy1[0].age = 22;
    console.log(arr, arrCopy1);
    /*
    [{"name":"shivaansh"}, {"name":"agarwal"}]
    [{"name":"shivaansh", "age":22}, {"name":"agarwal"}]
    */
    



    그러나 그녀가 지적한 것처럼 JSON JSON와 호환되지 않는 값으로는 작동하지 않으므로 기술이 실패할 수 있습니다. 배열 내부의 개체 속성에 할당되는 함수가 있다고 가정합니다.


    또한 다음 예를 고려하십시오.

    function nestedCopy(array) {
        return JSON.parse(JSON.stringify(array));
    }
    
    // undefined are converted to nulls
    nestedCopy([1, undefined, 2]) // -> [1, null, 2]
    
    // DOM nodes are converted to empty objects
    nestedCopy([document.body, document.querySelector('p')]) // -> [{}, {}]
    
    // JS dates are converted to strings
    nestedCopy([new Date()]) // -> ["2019-03-04T10:09:00.419Z"]
    


    lodash 또는 사용자 지정 함수로 deepClone



  • JSON.stringify/parse는 함수 또는 기호 속성이 없는 숫자, 문자열 및 개체 리터럴에서만 작동합니다.

  • deepClone은 모든 유형에서 작동하며 함수 및 기호는 참조로 복사됩니다.

  • 에 의한 Lodash 솔루션의 예,




    const lodashClonedeep = require("lodash.clonedeep");
    
    const arrOfFunction = [() => 2, {
        test: () => 3,
    }, Symbol('4')];
    
    // deepClone copy by refence function and Symbol
    console.log(lodashClonedeep(arrOfFunction));
    // JSON replace function with null and function in object with undefined
    console.log(JSON.parse(JSON.stringify(arrOfFunction)));
    
    // function and symbol are copied by reference in deepClone
    console.log(lodashClonedeep(arrOfFunction)[0] === lodashClonedeep(arrOfFunction)[0]);
    console.log(lodashClonedeep(arrOfFunction)[2] === lodashClonedeep(arrOfFunction)[2]);
    


    Tareq Al-Zubaidi의 재귀 함수 솔루션의 예




    const clone = (items) => items.map(item => Array.isArray(item) ? clone(item) : item);
    


    참조:


  • https://www.educative.io/courses/step-up-your-js-a-comprehensive-guide-to-intermediate-javascript/7nAZrnYW9rG
  • https://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value
  • https://www.freecodecamp.org/news/understanding-by-reference-vs-by-value-d49139beb1c4/
  • https://javascript.info/object-copy

  • WesBros의 Javascript30 과정
  • 좋은 웹페이지 즐겨찾기