2
2
この記事誰得? 私しか得しないニッチな技術で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

JavaScript に 参照(エイリアス)にあたる表現は ある

Last updated at Posted at 2024-06-23

この記事は 初心者が見ると混乱する要因になるので
初心者が見る資料 としては不適切です。
この特殊な条件でしか発生しないので通常のコーディングでは考慮する必要は無いです。
特に引数と arguments を 両用するのはとてもお勧めできません。
eslint の prefer-rest-params を有効にすることをおすすめします。

arguments と引数

言語的に参照渡しの無い言語である javascript には 参照渡しでいうところの 参照………つまり リファレンスではなく、いわゆる エイリアスにあたる動作は存在しない………と思っていたが、よくよく思っていたら存在したのでメモする。

具体的には次の様なコード

function func(arg1){
    console.log('step1: ', arg1 === arguments[0]);
    arg1 = {};
    console.log('step2: ', arg1 === arguments[0]);
    arguments[0] = {};
    console.log('step3: ', arg1 === arguments[0]);
}
console.log('test: ', {} === {});
func({});

この実行結果は

test: false
step1: true
step2: true
step3: true

となるつまり、 第一引数 は arguments[0] の参照(エイリアス)と言えるのである。

上記の例がわかりにくいというのであれば次の様な表現でもいいと思います。

function func(arg1){
    console.log('step1: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
    arg1 = "step2";
    console.log('step2: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
    arguments[0] = "step3";
    console.log('step3: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
}
func("step1");

この実行結果は次の様になります。

step1: true ('step1', 'step1')
step2: true ('step2', 'step2')
step3: true ('step3', 'step3')

仕様書では

この動作について仕様書 を読んだところ NOTE 2 として次の説明があった。

NOTE2
The integer-indexed data properties of an arguments exotic object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. If the arguments object is an ordinary object, the values of its properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.

10.4.4 Arguments Exotic Objects - ECMAScript® 2025 Language Specification

とあり、 パラメータ数 に一致する index の位置にあたるものに関しては共有するとあります。つまり arguments が主となり共有している様なので次の様な実験を行うことを考えます。

test1
function func(arg1) {
    console.log('deletable: %o', delete arg1);
    console.log('step1: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
    arg1 = "step2";
    console.log('step2: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
    arguments[0] = "step3";
    console.log('step3: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
}
func("step1");
test2
function func(arg1) {
    console.log('deletable: %o', delete arguments[0]);
    console.log('step1: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
    arg1 = "step2";
    console.log('step2: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
    arguments[0] = "step3";
    console.log('step3: %o (%o, %o)', arg1 === arguments[0], arg1, arguments[0]);
}
func("step1");

するとそれぞれ次の様な実行結果となります。

test1 output
deletable: false
step1: true ('step1', 'step1')
step2: true ('step2', 'step2')
step3: true ('step3', 'step3')
test2 output
deletable: true
step1: false ('step1', undefined)
step1: false ('step2', undefined)
step1: false ('step2', 'step3')

つまり arguments[n] を削除すると 引数との参照を切ることができるのです。

以上。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2