Javascript의 가치 VS 참조
20520 단어 programmingjavascript
개요
string
, number
, bigint
, boolean
, undefined
, symbol
. 하지만 null
동작 때문에 기본 데이터 유형으로 간주되지만 경우에 따라 null
처음 보이는 것처럼 "원시적"이 아닙니다! 모든 개체는 null
작성자 Prototypal Chain
따라서 typeof
연산자는 객체를 반환합니다. 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
이제 이전에 선언한
a2
및 b2
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);
참조:
Reference
이 문제에 관하여(Javascript의 가치 VS 참조), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shiv1998/value-vs-reference-in-javascript-22d7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)