JavaScript에는 "참조에 의한 전달 대 참조에 의한 전달"이 없습니다.
"JS 객체는 참조로 전달되고 프리미티브는 값으로 전달된다"는 속담 이 전달, 객체 또는 참조와 아무 관련이 없으며 사실 환상인 이유를 보여드리겠습니다 . "Objects-are-passed-by-reference"(OAPBR)는 이론/정신적 모델입니다. 대부분의 이론과 마찬가지로 이해, 예측, 제어에 대한 기여도와 복잡성 측면에서 비용을 기준으로 판단해야 합니다. 저는 이 예를 매우 부정확한 정신 모델이 다음과 같은 증거로 사용하기를 바랍니다.
- 고급 기능 학습을 더 어렵게 만듭니다.
- 다른 프로그래밍 언어 학습을 더 어렵게 만듭니다.
- 그리고 시간을 낭비합니다. 마지막에는 매우 부정확한 멘탈 모델을 피하기 위한 제안을 할 것입니다.
OAPBR(Objects are Passed by Reference) 이론이 설명하고자 하는 것을 보여주기 위해 먼저 두 가지 정의가 필요합니다.
function plusNum(n1, n2) {
return n1 + n2;
}
function mutatingAdd(obj1, n) {
obj1.value = plusNum(obj1.value, n)
}
function takeNum(n /* number */) {
n = plusNum(n, 1);
console.log(n); // 2
}
function primitiveExample() {
let x = 1;
takeNum(x);
console.log(x); // 1
}
function mutateObj(obj /* {field: number} */) {
mutatingAdd(obj, 1);
console.log(obj.value); // 2
}
function objectExample() {
let x = {value: 1};
mutateObj(x);
console.log(x.value); // 2
}
"객체가 참조로 전달됨"(OAPBR) 이론이 실패하는 방법
이제 함수를 사용하지 않도록 예제를 조정하여 이전 예제가 함수에 값을 전달하는 것과 아무 관련이 없음을 보여 드리겠습니다.
function primitiveExample2() {
let x = 1;
let y = x;
y = y + 1;
console.log(y); // 2
console.log(x); // 1
}
function objectExample2() {
let x = { value: 1 };
let y = x;
y.value = y.value + 1;
console.log(y.value); // 2
console.log(x.value); // 2
}
function combinedExample1() {
let x = Object.assign(1, { value: 100 });
let y = x;
mutatingAdd(y, 100);
console.log(y.value); // 200
console.log(x.value); // 200
y = plusNum(y, 1);
console.log(y + 0); // 2
console.log(x + 0); // 1
}
function nonMutatingPlusObj(obj1, obj2) {
return { value: obj1.value + obj2.value };
}
function nonMutatingObjectExample() {
let x = {value: 100};
let y = x;
y = nonMutatingPlusObj(y, {value: 100})
console.log(y.value); // 200
console.log(x.value); // 100
}
<?php
function add_mut(&$i1, $i2) {
$i1 += $i2;
}
$x = 1;
add_mut($x, 1);
echo $x; // 2
?>
fn add_mut(i: &mut i32, i2: i32) {
*i = (*i) + i2;
}
fn main() {
let i = &mut 1;
add_mut(i, 1);
println!("{}", i); // 2
}
function makeRef(thing) {
return {value: thing};
}
function addMut(iRef, i2) {
iRef.value = iRef.value + i2;
}
let iRef = makeRef(1);
addMut(iRef, 1);
console.log(iRef.value); // 2
더 나은 이론
"객체는 참조로 전달되고 프리미티브는 값으로 전달됩니다" 대신 범위 변경과 값 변경 사이의 더 나은 구분을 제안합니다. JS에서 범위는 변수 이름에서 값으로의 변경 가능한 매핑입니다.
let x = 1; // the scope maps x to 1
x = 2; // the scope maps x to 2
x += 1; // the scope maps x to 3
각 함수가 새로운 범위를 도입하기 때문에 함수 컨텍스트에서 "참조에 의한 전달" 환상이 발생할 수 있습니다. MDN의 범위에 대해 자세히 알아보십시오 .
아래 코드에서 동일한 개체를 가리키면 x변경 됩니다. 범위를 변경하지 않습니다. JavaScript 함수는 닫히지 않는 범위를 변경할 수 없기 때문입니다.ymutateObjmutatingAdd
function objectExample() {
let x = {value: 1};
let y = x;
mutatingAdd(y, 1);
console.log(y.value); // 2
console.log(x.value); // 2
}
특히 JS의 경우 범위가 변경 가능하다는 것을 이해하는 것은 const-vs-let, 그림자, 개체 ID, 클로저 및 UI 작성을 이해하는 데 필수적입니다. 그리고 이는 잘못된 "값 기준 대 참조 기준" 구분과 비교할 때 매우 단순한 개념입니다.
무엇 향후 계획
프로그래밍 언어에 대한 나쁜 정신 모델이 다음 소스에서 나오는 것을 보았습니다.
- 학습 리소스를 사용하지 않고 대신 다이빙하여 프로그래밍을 시도합니다. 이것은 빠르게 느껴질 수 있지만 장기적으로는 느린 경로라고 생각합니다.
- 블로그 게시물이나 동영상을 통해 학습합니다. (나는 이것이 블로그 게시물이라는 것을 알고 있습니다: 여기에서 무엇보다 MDN을 신뢰하십시오.)
- 프로그래밍 언어 기능이 명백하다고 가정합니다. 명백한 것은 없으며, 특히 변수는 없으며 프로그래밍 언어 간에 작동 방식에 대한 놀라운 차이가 있습니다.
행복한 해킹!

![연결된 목록이란 무엇입니까? [1 부]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































