JavaScript には「参照渡し vs. JavaScript」がありません。
「JS オブジェクトは参照によって渡され、プリミティブは値によって渡される」という俗説が、受け渡し、オブジェクト、参照とは何の関係もなく、実際には幻想である理由を説明します。「オブジェクトは参照によって渡される」 (OAPBR) は理論/精神モデルです。ほとんどの理論と同様に、理解、予測、制御への貢献、および複雑さの観点からのコストに基づいて判断される必要があります。この例を、メンタル モデルが非常に間違っているという証拠として使用したいと考えています。
- 高度な機能の学習が難しくなる
- 他のプログラミング言語の学習が難しくなる
- そして時間を無駄にします。最後に、非常に不正確なメンタルモデルを避けるための提案をします。
「オブジェクトは参照によって渡される」(OAPBR) 理論が何を説明しようとしているのかを示すには、まず 2 つの定義が必要です。
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)



































