再宣言の差異は
再宣言可なvarと再宣言不可のlet。
どっちがいいのか微妙だけど、外部変数の宣言の場合には・・・
概ね宣言が被る方が困るので、letにしておこう。
尚、スコープの差異は
ブロックスコープなletの方が関数スコープのvarより使いやすい。
結論、varは要らない。
この画面は、簡易表示です
再宣言の差異は
再宣言可なvarと再宣言不可のlet。
どっちがいいのか微妙だけど、外部変数の宣言の場合には・・・
概ね宣言が被る方が困るので、letにしておこう。
尚、スコープの差異は
ブロックスコープなletの方が関数スコープのvarより使いやすい。
結論、varは要らない。
const createHtmlElement = (elementName, options) => {
・・・
・・・
const rc = Object.keys(options).map(
(key) => (chkOriginal(key) || chkStyle(key) || chkEvent(key) || setAttribute(key)));
);
}
と書くと、呼び出された各処理で
function chkOriginal(key) {
const value = options[key];
...
}
function chkStyle(key) {
const value = options[key];
...
}
function chkEvent(key) {
const value = options[key];
...
}
function setAttribute(key) {
const value = options[key];
...
}
と書いてたけど・・・
const createHtmlElement = (elementName, options) => {
・・・
const chkOriginal = (key,value) => {
...
}
const chkStyle = (key,value) => {
...
}
const chkEvent = (key,value) => {
...
}
const setAttribute = (key,value) => {
...
}
・・・
const rc = Object.keys(options).map(
const value = options[key];
(key) => (chkOriginal(key,value) || chkStyle(key,value) || chkEvent(key,value) || setAttribute(key,value)));
);
}
としてみた。自分で書いたコードから、ローカル関数で元関数のパラメータを見ても特に支障は無いけど、functionを使わない書き方で統一できた。
MDNを見ると、mapでも第2パラメータ(thisArgs)が使えるみたいなので、
const rc = Object.keys(options).map(function (key) {
const value = this[key];
return chkOriginal(key, value) || chkStyle(key, value) || chkEvent(key, value) || setAttribute(key, value);
}, options);
としてみた。
本来はコールバックに特定のオブジェクトをthisとして引き渡したい場合に使うものだし、コールバックの中でoptionsを書きたくないと意地を張ったものの、optionsを2回書いてしまう事に変わりは無いので、無駄なthisArgsの使い方になってしまった。外部の変数を見てる怪しい部分も修正したら結果がコレ。
/**
* HTMLエレメントを作成する
* @param {string} elementName エレメント名
* @param {{attributeName:,... eventName:,...}}} options 設定内容
* @returns {HTMLElement} 作成したHTMLElement
*/
const createHtmlElement = (elementName, options) => {
const fileName = 'js/lib/createHtmlElement.js';
const funcName = 'createHtmlElement'; //debugLog(`${fileName}:${funcName}(elementName: ${elementName}, options)`);
/**
* 独自の処理が必要な場合
* @param {} param 属性
* @returns {boolean} 結果
*/
const chkOriginal = (param) => {
let rc = false;
try {
switch (param.name) {
case 'className': // classNameはメソッドで、\x20で文字列を区切って複数の属性を指定できる
case 'classList': // classListはメソッド
let v = param.value;
if (!Array.isArray(v)) { v = v.split('\x20'); }
param.element.classList.add(...v); // 配列を展開してクラスリストに追加する
rc = true;
break;
case 'innerHTML': // innerHTMLはメソッド扱い ※未使用
param.element.innerHTML = param.value;
rc = true;
break;
case 'innerText': // innerTextはメソッド扱い
param.element.innerText = param.value;
rc = true;
break;
case 'parent': // parentはメソッド
param.value.appendChild(param.element);
rc = true;
break;
case 'appendChild': // appendChildはメソッド ※未使用
param.element.appendChild(param.value);
rc = true;
break;
case 'insertBefore': // insertBeforeはメソッド ※スクロール処理で座標の小さい方向へセルを作る際に使用
param.value.parentNode.insertBefore(param.element, param.value);
rc = true;
break;
} // end of switch
} catch (ex) {
debugLog(`${funcName}(elementName: ${elementName}) '${param.name}'属性の固有処理に失敗 '${ex}'`);
rc = false;
}
return rc;
};
/**
* スタイル属性の場合
* @param {} param 属性
* @returns {boolean} 結果
*/
const chkStyle = (param) => {
let rc;
try {
// style-xxxxのキーの場合
let styleChk = param.name.match(/^style_(.*)/);
if (styleChk) {
let styleName = styleChk[1];
switch (styleName) {
case 'width':
param.element.style.width = param.value;
break;
case 'height':
param.element.style.height = param.value;
break;
default:
styleChk = null;
break;
} // end of switch
}
rc = styleChk !== null;
} catch (ex) {
debugLog(`${funcName}(elementName: ${elementName}) '${param.name}'スタイル属性に${param.value}を設定失敗 '${ex}'`);
rc = false;
}
return rc;
}
/**
* eventの場合
* @param {} param 属性
* @returns {boolean} 結果
*/
const chkEvent = (param) => {
let rc;
try {
const eventList = ['ended']; // イベントリスト
rc = eventList.includes(param.name); // イベントリストに含まれているかどうか
if (rc) { // イベントリスナを登録する
param.element.addEventListener(param.name, param.value);
}
} catch (ex) {
debugLog(`${funcName}(elementName: ${elementName}) '${param.name}'イベントリスナの登録に失敗 '${ex}'`);
rc = false;
}
return rc;
}
/**
* HTMLエレメントに属性を追加する
* @param {} param 属性
* @returns {boolean} 結果
*/
const setAttribute = (param) => {
try {
param.element.setAttribute(param.name, param.value);
return true;
} catch (ex) {
debugLog(`${funcName}(elementName: ${elementName}) '${param.name}'属性に${param.value}を設定失敗 '${ex}'`);
return false;
}
}
let elm = document.createElement(elementName);
// optionsの設定名を取得しぶん回す!
const rc = Object.keys(options).map(function (key) {
const value = this[key];
const param = { 'name': key, 'value': value, 'element': elm };
return chkOriginal(param) || chkStyle(param) || chkEvent(param) || setAttribute(param);
}, options)
.filter(v => !v); // trueならば削除する
if (0 < rc.length) {
debugLog(`${funcName}(elementName: ${elementName}) 未処理属性数:${rc.length}件`);
}
return elm;
}
数か月経つと
※未使用
と書かないと、「どこかで使っている(気がする」し、
※スクロール処理で座標の小さい方向へセルを作る際に使用
とか書いておかないと、「要らない(気がする」する、
なぜか、逆バイアスがかかってしまうのは・・・謎。
あ、使い方も忘れた。
こんな感じだった。
let a = createHtmlElement('a', {
href: url,
download: fileName,
text: "re-download",
});
色々設定したいHTMLエレメントを作る時に
const div = createElement('div');
shadow.addChiled(div);
div.className = 'scroll';
div.id = `div${sn}`;
div.style.height = _spreadSheet.width;
div.style.width = _spreadSheet.height;
div.tabIndex = `${sn}`;
を1行で書ける。更にそんなモノがいっぱいある場合には、
// シャドールートを作成
_layout.shadowRoot = (!_layout.shadowRoot) ? _spreadSheet.customElement.attachShadow({ mode: "open" }) : _layout.shadowRoot;
const shadow = _layout.shadowRoot;
// 既存のHTMLElementを削除
Array.from(_layout.shadowRoot.children).forEach((ch) => ch.remove());
// スタイルシート部
const style = _layout.createStyle(sn, _spreadSheet.rows, _spreadSheet.cols, true, true);
shadow.appendChild(style);
// スプレッドシート部
_layout.divTableN = createHtmlElement('div', { parent: shadow, className: 'scroll', id: `div${sn}`, style_height: _spreadSheet.width, style_width: _spreadSheet.height, tabIndex: `${sn}`, });
_layout.tableN = await _layout.createTableElement(_layout.divTableN, 'spread-sheet', `table${sn}`);
_layout.divScrollX = createHtmlElement('div', { parent: _layout.divTableN, className: 'scroll-x', id: `divScrollX${sn}`, style_height: '17px', style_width: _spreadSheet.height, tabIndex: `${sn}`, });
_layout.divScrollY = createHtmlElement('div', { parent: _layout.divTableN, className: 'scroll-y', id: `divScrollY${sn}`, style_height: _spreadSheet.width, style_width: '17px', tabIndex: `${sn}`, });
と書け、すっきりする。
もっとも、インターネットの記事でそんなケースはまず有り得ないし、必要に応じてcreateHtmlElementの機能を増設していかないと「すっきり」しないので、仕事で作るソースにも使ったことはないね。
最初はcreateDivElementとかcreateAElementとかタグ毎に作っていたけど多すぎるので、createTableElementを除いて一本化した。
createTableElementみたいに複雑で同期を取る必要もあるモノは別物にするしかないが、コード全般の流れを単純化するとスッキリした。勿論、createTableElementの中のアチコチでcreateHtmlElementを呼び出している。
今見ると、イベント登録まで入れたのはやり過ぎ感があるなぁ。
Ctrl+Sでデータのダウンロードするとエラっていたので、修正。
メニューの「ファイル」で
「プロファイルを含む新しいウインドウ」⇒「新しいプロファイル…」を選択すると、
「新しいプロファイル」のウインドウが出るので
「v」⇒「テンプレートから」で、言語が色々選べる。
何に使うのかと云えば、チームでアプリを開発する際に、「プロファイルのインポート」で、同じプロファイルを使う様にすると開発環境(スニペや拡張機能のインストとか)を揃える手間が減るかもしれない。
でも、使い道がよく判りません。
画面左下の「設定(歯車)」の内容も随分増えてる。
訳が判らない。
WebAssemblyを使いたくてemscriptenをインスト。
まずはcドライブのルートで「ターミナルを開く」。※最新PowerShellに連動済み
PowerShell 7.4.5
PS C:\> git clone https://github.com/emscripten-core/emsdk
Cloning into 'emsdk'...
remote: Enumerating objects: 4162, done.
remote: Counting objects: 100% (97/97), done.
remote: Compressing objects: 100% (76/76), done.
remote: Total 4162 (delta 47), reused 54 (delta 19), pack-reused 4065 (from 1)
Receiving objects: 100% (4162/4162), 2.38 MiB | 1.65 MiB/s, done.
Resolving deltas: 100% (2722/2722), done.
PS C:\> cd emsdk
PS C:\emsdk> ./emsdk.bat install latest
Resolving SDK alias 'latest' to '3.1.65'
Resolving SDK version '3.1.65' to 'sdk-releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit'
Installing SDK 'sdk-releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit'..
Installing tool 'node-18.20.3-64bit'..
Downloading: C:/emsdk/downloads/node-v18.20.3-win-x64.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v18.20.3-win-x64.zip, 30476796 Bytes
Unpacking 'C:/emsdk/downloads/node-v18.20.3-win-x64.zip' to 'C:/emsdk/node/18.20.3_64bit'
Done installing tool 'node-18.20.3-64bit'.
Installing tool 'python-3.9.2-nuget-64bit'..
Downloading: C:/emsdk/downloads/python-3.9.2-4-amd64+pywin32.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/python-3.9.2-4-amd64+pywin32.zip, 14413267 Bytes
Unpacking 'C:/emsdk/downloads/python-3.9.2-4-amd64+pywin32.zip' to 'C:/emsdk/python/3.9.2-nuget_64bit'
Done installing tool 'python-3.9.2-nuget-64bit'.
Installing tool 'java-8.152-64bit'..
Downloading: C:/emsdk/downloads/portable_jre_8_update_152_64bit.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/portable_jre_8_update_152_64bit.zip, 69241499 Bytes
Unpacking 'C:/emsdk/downloads/portable_jre_8_update_152_64bit.zip' to 'C:/emsdk/java/8.152_64bit'
Done installing tool 'java-8.152-64bit'.
Installing tool 'releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit'..
Downloading: C:/emsdk/downloads/fdcf56c75a1d27fdff6525a7e03423595485ca19-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/fdcf56c75a1d27fdff6525a7e03423595485ca19/wasm-binaries.zip, 523605271 Bytes
Unpacking 'C:/emsdk/downloads/fdcf56c75a1d27fdff6525a7e03423595485ca19-wasm-binaries.zip' to 'C:/emsdk/upstream'
Done installing tool 'releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit'.
Done installing SDK 'sdk-releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit'.
PS C:\emsdk> ./emsdk.bat activate latest
Resolving SDK alias 'latest' to '3.1.65'
Resolving SDK version '3.1.65' to 'sdk-releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit'
Setting the following tools as active:
node-18.20.3-64bit
python-3.9.2-nuget-64bit
java-8.152-64bit
releases-fdcf56c75a1d27fdff6525a7e03423595485ca19-64bit
Next steps:
- Consider running `emsdk activate` with --permanent or --system
to have emsdk settings available on startup.
Adding directories to PATH:
PATH += C:\emsdk
PATH += C:\emsdk\node\18.20.3_64bit\bin
PATH += C:\emsdk\upstream\emscripten
Setting environment variables:
PATH = C:\emsdk;C:\emsdk\node\18.20.3_64bit\bin;C:\emsdk\upstream\emscripten;C:\Program Files\WindowsApps\Microsoft.PowerShell_7.4.5.0_x64__8wekyb3d8bbwe;C:\app\[ユーザ名]\product\19.0.0\client_1;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\PROGRA~1\JPKI;C:\Program Files\Git\cmd;C:\Users\[ユーザ名]\AppData\Local\Microsoft\WindowsApps;C:\Users\[ユーザ名]\AppData\Local\Programs\Microsoft VS Code\bin
EMSDK = C:/emsdk
EMSDK_NODE = C:\emsdk\node\18.20.3_64bit\bin\node.exe
EMSDK_PYTHON = C:\emsdk\python\3.9.2-nuget_64bit\python.exe
JAVA_HOME = C:\emsdk\java\8.152_64bit
Clearing existing environment variable: EMSDK_PY
The changes made to environment variables only apply to the currently running shell instance. Use the 'emsdk_env.bat' to re-enter this environment later, or if you'd like to register this environment permanently, rerun this command with the option --permanent.
インストしたが、
PowerShell 7.4.5
PS C:\emsdk> emmake
emmake: The term 'emmake' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
環境変数を追加しないといけないらしい。
悩んだ末emcmdprompt.batの存在に気が付いた。
PowerShellじゃないけどね(笑
やっとコマンドが使えるようになったのでインスト完了。
どこのフォルダでも使える様にするには
emsdk activate --permanent or --system
で環境変数を直接書き換えてしまった方がいいだろう。(※未確認
さて、インストしたらどれくらいのサイズを使ったのかな?
なんてこったい!1.63GBもある!
node.jsとpythonとJavaも入っている様だから仕方が無いかな?
旧名draw.ioの描画ツール。
MicrosoftStoreからインストールできファイル作成もテンプレ選択があるので使いやすい。
VScodeの拡張機能でもインスト可能だがいつものようにファイルの拡張子に連動してメニューが出る仕組みなので、まずdrawio拡張子でファイルを新規作成しなければ触ることすらできないし、一見するとテンプレは無い様に観えるが、メニューの+の中にテンプレがある。
メニューの+の「高度な設定」がなかなか奥が深い。
スクラッチパッドがあるのであちこちに図形の組み合わせを複製するのが楽そう。
メニューのファイル>Exportから、svgやpngファイルに出力できるので、こんな感じの図形をブログの記事に埋め込むこともできるから使い道は結構ありそう。
欲を云えば、MS-WORDやMS-EXCELと線画のままコピペできたら便利そうだけど、どっちもインストしてないマシン(例えばスマホ等)で観れないだろうから、注意して取り扱わないといけない気がする。
MS-ExcelやGooleのSpreadSheetの図形や肝心な機能を制限してる無償ツールでUMLなシーケンス図描きに悩まさたのを思い出した。適材適所って重要だよね?(大笑
残念ながらStoreには無いので、公式のDownloadボタンでexeファイルをダウンンロード。
ここからは長い。基本Nextボタンで進めるが、
GitのエディタをVisualStudio Codeに変更する。
新規リポジトリ作成時のブランチの名前は手入力に変更する。
他への影響を抑えつつPowerShellからもgitを使えるようオプションを選択する。
シンボリックリンクも使えるオプションを追加で選択する。
で、インスト開始。
これでスタートの全てのアプリで見れるハズ。
このGit BashでGitでのデフォルトのアカウントを設定しておく。
git config --global user.name "ユーザー名"
今の最新版はバージョン3.12.5だから、
StoreからPython 3.12をインストール。
開くと
ターミナルから起動すると
フォルダとかでターミナルを開くと
アップデートしよう!と毎回出てくる。
ちなみに今現在は・・・
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.22621.4111
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.22621.4111
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
先のリンク先へジャンプすると・・・
のページが開くが、インストール方法s(msiファイルとかzipファイルとか…)の解説ページだった。
その中で一番簡単そうなのはMicrosoft Storeからのダウンロードだ。
Microsoft StoreでPowerShellを検索すると
表記されたバージョンが古いとおもったけど「4.2★」が、「人気度4.2」の意味だった。
アプリ名の下の数値は普通「人気度」なんだけど、
ツール系のアプリの場合はその前にバージョンを表記するのが普通だから・・・紛らわしい。
PowerShellのプレートにマウスをフォーカスすると、取得済み(アンスコした後なせいかな?)からインストールに変わるのでボタンを押す。
PowerShell 7.4.5
PS C:\Windows\System32> $PSVersionTable
Name Value
---- -----
PSVersion 7.4.5
PSEdition Core
GitCommitId 7.4.5
OS Microsoft Windows 10.0.22631
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
無事今の最新版になったのでこれでOK。
と思ったが、フォルダからターミナルで開くをすると古いまま。
スタートの全てのアプリからPowerShellをスタートにピン止めしクリックすれば新しいバージョンが起動できるけど、他は古いまま。
サイドバイサイド(同じOSで新旧のバージョンがどっちも使える)だけどさぁ?
新旧どうやって使い分ければいいのかな?
ちなみに
環境変数PATHを確認してみるとC:\Program Files\PowerShell\7がありここにインストしたかのように見えるが、削除して再インスコしても出てこないので、これは過去のインスーラのせいな気がする。
実際には他のアプリ同様にC:\Users\[ユーザ名]\AppData\Local\Microsoft\WindowsAppsにpwsh.exeとしてインストされている。
Microsoft Windows [Version 10.0.22631.4112]
(c) Microsoft Corporation. All rights reserved.
C:\Users\[ユーザ名]>where pwsh.exe
C:\Users\[ユーザ名]\AppData\Local\Microsoft\WindowsApps\pwsh.exe
先のページではバージョン別の居場所は
Windows PowerShell 5.1 | $env:WINDIR\System32\WindowsPowerShell\v1.0 |
PowerShell 6.x | $env:ProgramFiles\PowerShell\6 |
PowerShell 7 | $env:ProgramFiles\PowerShell\7 |
となっているが、C:\ProgramFiles\PowerShellなんてフォルダすらできてない。
C:\Windows\System32\WindowsPowerShell\v1.0にはpowershell.exeがあるのでこれが旧バージョンらしい。
Microsoft Windows [Version 10.0.22631.4112]
(c) Microsoft Corporation. All rights reserved.
C:\Users\[ユーザ名]>where powershell.exe
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
つまり、現在はEXEのファイル名で新旧バージョンを切り替えて使うのが良いのかもしれない。
と云う訳で、新版はターミナルでpwshで起動するのが一番簡単かな?
ターミナルのタイトルの「v」の設定の「新しいプロファイルを追加します」から
新バージョン用のプロファイルを作ってみた。
注意点としてはコマンドラインを指定する際に参照ボタンからpwsh.exe ファイルを探し出して開くボタンを押してしまうと
となってしまうので、見つけたpwsh.exeでパスのコピーでクリップボードに入れ、エントリーボックスに貼り付ける様にすることかな?
ついでに旧版のプロファイルの名前にバージョンを加えてみた。
最後に設定のスタートアップで新バージョンを指定した。
これで、フォルダのターミナルを開くで、すぐPowerShell新バージョンで使える。
とりあえずコレで良い???かな???????
時々Google Chromeのセキュリティ・アップデートの記事を見るけど、多すぎない?
自動的にアップデートして欲しいけど、そうなると・・・
たまに~~~的な状況もありそうだから、しないんだろうけど。
今時のペイントで①とか描くと円の上が切れるんだね(笑