さらに別の環境検出:
(意味:ここでの答えのほとんどは大丈夫です。)
function isNode() {
return typeof global === 'object'
&& String(global) === '[object global]'
&& typeof process === 'object'
&& String(process) === '[object process]'
&& global === global.GLOBAL // circular ref
// process.release.name cannot be altered, unlike process.title
&& /node|io\.js/.test(process.release.name)
&& typeof setImmediate === 'function'
&& setImmediate.length === 4
&& typeof __dirname === 'string'
&& Should I go on ?..
}
少しパラノイアでしょ?より多くのグローバルをチェックすることで、これをより冗長にすることができます。
しかし、しないでください!。
上記のすべてはとにかく偽造/シミュレートすることができます。
たとえば、global
オブジェクトを偽造するには:
global = {
toString: function () {
return '[object global]';
},
GLOBAL: global,
setImmediate: function (a, b, c, d) {}
};
setImmediate = function (a, b, c, d) {};
...
これはノードの元のグローバルオブジェクトにアタッチされませんがwindow
、ブラウザのオブジェクトにアタッチされます。つまり、ブラウザ内のNodeenvにいることを意味します。
人生は短いです!
私たちの環境が偽造されているかどうかは気になりますか?これは、愚かな開発者がグローバルスコープで呼び出されるグローバル変数を宣言したときに発生しglobal
ます。または、いくつかの邪悪な開発者がどういうわけか私たちの環境にコードを挿入します。
これをキャッチするとコードの実行が妨げられる可能性がありますが、アプリの他の多くの依存関係がこれに巻き込まれる可能性があります。したがって、最終的にコードは壊れます。コードが十分に優れている場合は、他の人が行った可能性のあるすべてのばかげた間違いを気にする必要はありません。
だから何?
2つの環境を対象とする場合:ブラウザとノード。
"use strict"
; または単にチェックするwindow
かglobal
; また、ドキュメントで、コードがこれらの環境のみをサポートしていることを明確に示します。それでおしまい!
var isBrowser = typeof window !== 'undefined'
&& ({}).toString.call(window) === '[object Window]';
var isNode = typeof global !== "undefined"
&& ({}).toString.call(global) === '[object global]';
可能であれば、ユースケースで。環境検出の代わりに; try/catchブロック内で同期機能検出を実行します。(これらの実行には数ミリ秒かかります)。
例えば
function isPromiseSupported() {
var supported = false;
try {
var p = new Promise(function (res, rej) {});
supported = true;
} catch (e) {}
return supported;
}