LoginSignup
0
0

More than 1 year has passed since last update.

Javascript 「~ is read-only」エラー解決法

Posted at

目的

「~ is read-only」エラーが出たので、解決法を調査する。

現状

show.jsのcreatePhraseListTableNodeからlib.jsの関数を呼び出して、
trNodeという変数で「trNode is read-only」というエラーが出ている。

show.js
const PhrasesTable = createPhraseListTableNode(phraseList);
lib.js
const createPhraseListTableNode = (phraseList) => {
  const tableNode = document.createElement('table');
  tableNode.setAttribute('id', 'phrase-list');
  const theadNode = document.createElement('thead');
  const tbodyNode = document.createElement('tbody');
  const trNode = document.createElement('tr');

  let thVals = ['単語', '意味', ''];
  for (let i = 0; i < thVals.length; i++) {
    const thNode = document.createElement('th');
    thNode.innerText = thVals[i];
    trNode.appendChild(thNode);
  }

  for (let phrase in phraseList) {
    trNode = createPhraseTrNode(phrase);
    tbodyNode.appendChild(trNode);
  }
  tableNode.appendChild(theadNode);
  tableNode.appendChild(tbodyNode);

  return tableNode;
}

const createPhraseTrNode = (phrase) => {
  const trNode = document.createElement('tr');
  const contentTdNode1 = document.createElement('td');
  contentTdNode1.innerText = phrase.content;
  const meaningTdNode = document.createElement('td');
  meaningTdNode.innerText = phrase.meaning;
  const btnTdNode = document.createElement('td');
  const btnNode = document.createElement('button')
  btnNode.value = "削除"
  btnTdNode.appendChild(btnNode);

  return trNode;
}

エラー内容

実際に調べてみるとこのエラーはJavascriptの厳密モードにおいて、割り当てられたグローバル変数やオブジェクトプロパティが読み取り専用であることを表している。

推測

  • 読取専用の変数に対して代入しようとしている。
    • つまり今回は「trNode」という読取専用の変数に対して代入している場所が怪しい

「trNode」という変数に代入している場所を探すと、以下のような記述がある。

lib.js
const createPhraseListTableNode = (phraseList) => {
 ...
    trNode = createPhraseTrNode(phrase);
 ...
}

先頭で作成しているtrNodeという変数はthead作成の際に使用されている。その後tbodyを作成のループに入った際に代入しようとして先程のエラーが出たのではないかと考える。

// phraseListを tableにして返す
const createPhraseListTableNode = (phraseList) => {
  const trNode = document.createElement('tr');

  // theadの作成
  for (let i = 0; i < thVals.length; i++) {
    const thNode = document.createElement('th');
    trNode.appendChild(thNode);
  }
 //tbodyの作成
  for (let phrase in phraseList) {
    let bodyTrNode = createPhraseTrNode(phrase);
    tbodyNode.appendChild(bodyTrNode);
  }
  tableNode.appendChild(theadNode);
  tableNode.appendChild(tbodyNode);

  return tableNode;
}

解決

  • thead作成とtbody作成の際に同じtrNodeという変数を使用していることが問題

- thead用とtbody用の変数に明確に分ける。

lib.js
const createPhraseListTableNode = (phraseList) => {
  ...
  let thVals = ['単語', '意味', ''];
  // thead用のtrNode変数
  const headTrNode = document.createElement('tr');
  for (let i = 0; i < thVals.length; i++) {
    const thNode = document.createElement('th');
    thNode.innerText = thVals[i];
    headTrNode.appendChild(thNode);
  }

  for (let phrase in phraseList) {
    // tbody用のtrNode変数
    let bodyTrNode = createPhraseTrNode(phrase);
    tbodyNode.appendChild(bodyTrNode);
  }
  tableNode.appendChild(theadNode);
  tableNode.appendChild(tbodyNode);

  return tableNode;
}

参考

0
0
1

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