◆ 一度実行すると remove しても再 append しても実行できない
◆ 別のドキュメントにいれてもダメ
◆ 新しい script 要素作って innerHTML をコピーするのと動く
◆ eval や Function に innerHTML いれるのが簡単 

script タグを動的に追加することでスクリプトを実行できます
var s = document.createElement("script")
s.innerHTML = "console.log(11)"
document.head.appendChild(s)
// 11

再実行できない

実行後に取り除いて
s.remove()

もう一回 DOM に append しても
document.head.appendChild(s)

なにも起きません

2 回目の実行ができなくなっています


クローンしてそっちを append しても
s.remove()
var s2 = s.cloneNode(true)
document.head.appendChild(s2)

なにも起きません


innerHTML を書き換えても
s2.remove()

s.innerHTML = "console.log(12)"
s2.innerHTML = "console.log(12)"

document.head.appendChild(s)
document.head.appendChild(s2)

やっぱり何も起きません

中身が空の script タグ

また 中身が空の場合は
var s4 = document.createElement("script")
document.head.appendChild(s4)

ここでは何も起きず
s4.innerHTML = "console.log(13)"
// 13

innerHTML を編集したタイミングで実行されます

実行済みかの情報はどこにもってるの?

プロパティに isExecuted みたいなのあるのかと思いましたがざっと見た感じなさそうです

一応 for in でチェックしてみても
var sa = document.createElement("script")
var sb = document.createElement("script")

sa.innerHTML = ";"
sb.innerHTML = ";"

document.head.appendChild(sa)
sa.remove()

for(var k in sa) sa[k] !== sb[k] && console.log(k)
dataset
style
classList
attributes
children
childNodes
firstChild
lastChild

オブジェクトなので参照が違うものだけです

別ドキュメントに append

var ss = document.createElement("script")
ss.innerHTML = "console.log(11)"
document.head.appendChild(ss)

一度 append したあとに iframe の別ドキュメントに append してみます
var iframe = document.createElement("iframe")
document.body.appendChild(iframe)
iframe.contentDocument.head.appendChild(ss)

これでも実行されません

document 側で実行済み script タグの参照を持っているのではなく script タグが内部で実行済みかの情報を持ってるみたいです

再実行するには

単純に考えるとその script 要素がだめなんだから 新しい要素に innerHTML だけをコピーすれば大丈夫そうです
var sx = document.createElement("script")
sx.innerHTML = "console.log(11)"
document.head.appendChild(sx)
// 11

var sy = document.createElement("script")
sy.innerHTML = sx.innerHTML
document.head.appendChild(sy)
// 11

無事動きました


毎回 document.createElement するのも面倒なので Function 関数で innerHTML を JavaScript コードとして実行することもできます
Function(sx.innerHTML)()


eval にもできます
eval(sx.innerHTML)

innerHTML の中の script タグ

エディタでコード書いてサッとブラウザで確認するときに わざわざ html ファイルで保存して開くなんて面倒ですよね
なので 私はよく その場で devtools を開いて Element タブの html タグを右クリックして 「Edit as HTML」 を選んでそこに貼り付けてます

そういうときにスクリプトタグが入っていても動きません
document.head.innerHTML = "<script>console.log(11)</script>"

これは何もおきません


なので JavaScript 部分だけコンソールタブに再度コピペして貼り付けるようにしていたのですが ↓ のコードをスニペット登録などしておいてすぐに呼び出せるようにしておけばお手軽感がさらにあがりそうです
;[...document.scripts].forEach(function(e){
var s = document.createElement("script")
e.src ? (s.src = e.src) : (s.innerHTML = e.innerHTML)
s.async = false
document.head.append(s)
s.remove()
})

やってるのは全部の script に対して 新しい script を作って src または innerHTML をコピーして head に追加です
script タグが増えるのですぐに remove しています

関係ないものも実行されそうですが HTML タグ以下全体を試したいコードに書き換えているなら 関係ないタグはないはずということで全部が対象です