1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】何も考えずfill()で横着して初期化しない

Last updated at Posted at 2020-09-07

初めに

fill()でずぼらして初期化したら思った挙動にならなかったので備忘録。
実際のコードを引っこ抜いてちょっと変えてるので変な感じになってるかも。

JavaScriptは最近やり始めましたがよくわからんですね。

起こったこと

以下のような変数を作成した

sub.ts
export const FuncA = (): HogeHoge => {
    const [a, setA] = useState("0");
    const [b, setB] = useState("0");
    retunrn {
        parameter: {a,b},
        setter: {setA,setB}
    };
}

fill(funcA)をしたparameters配列のそれぞれの要素を突っ込んだテーブルを以下みたいな感じで作る。

main.tsx
function TableBody(params: Params){
    const parameters = Array(params.lineCount).fill((FuncA));

    return (
        <table>
            <thead>...</thead>
            <tbody> { getLines(parameters) } </tbody>
        </table>
    );
}
...
function getLines(foo: Array<FuncA>) {
    return ([...Array<number>(foo.length)].map((_, i) => {
        return (
            <tr>
                <td>{ i + 1}</td>
                <td>
                    <label>A: <input type="number" value={foo.parameter.a} onChange={(e) => foo.setter.setA(e.target.value)} /></label><br />
                    <label>B: <input type="number" value={foo.parameter.b} onChange={(e) => foo.setter.setB(e.target.value)} /></label>
               </td>
            </tr> 
        )
    }));
}

全てのinputが独立して変更されることを想定していたが、
画面上でinputの値を変更したばあい全ての行の値が変更された。

FuncAの定義をexport const FuncA(){...}にしてfill( ()=> FuncA())とかにもしたけど同じだった。

よくわからないけど直した

fill()をやめてmap()で割り当てたら独立した。
fill(0)をしている場合上記みたいなことにならないので、
非プリミティブ型の場合は参照で引きたわされるのだろうか。
(そもそも関数を変数に入れること自体がこれまでなかったのでそこの挙動の把握も実は微妙)

const parameters = [...Array(params.lineCount)].map(() => FuncA());

おそらくこの部分の記載に基づくもの

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill
Polyfillのが同等の実装らしいので少し見たところ
var O = Object(this);のところが多分そうかなとは思った。

Objectのコンストラクタのページは404だったが、Objectクラスの説明に以下の記載があった。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object
Object コンストラクターは、指定された値のオブジェクトラッパーを生成します。

  • 値が null または undefined である場合、空のオブジェクトを生成して返します。
  • それ以外の場合は、与えられた値に関連する型のオブジェクトを返します。
  • 値がすでにオブジェクトであった場合は、その値を返します。

少し調べた感じJavaScriptもプリミティブ型はオブジェクトではなさそうなので、
プリミティブ型は2つ目の挙動、それ以外の場合は3つ目の挙動になるのだろうか。
この「その値」というのが複製ではなく引き渡したオブジェクト自体がかえるという意味であれば納得できる。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?