UWAGA: To pytanie składa się z dwóch części, ale ponieważ tytuł brzmiał "Wykrywanie środowiska: node.js lub przeglądarka" - najpierw przejdę do tej części, ponieważ myślę, że wiele osób przychodzi tutaj, by szukać odpowiedzi do tego. Oddzielne pytanie może być w porządku.
W zmiennych JavaScript może zostać na nowo przez wewnętrzne zakresach, a więc przy założeniu, że środowisko nie stworzył zmiennych nazwanych jako proces, globalne lub okno może łatwo zawieść, na przykład jeśli ktoś jest za pomocą modułu node.js jsdom The API usage example has
var window = doc.defaultView;
Po czym wykrycie środowiska w oparciu o istnienie zmiennej window
zakończy się systematycznie niepowodzeniem przez dowolny moduł działający pod tym kątem. Przy tej samej logice każdy kod oparty na przeglądarce mógłby z łatwością nadpisać global
lub process
, ponieważ nie są one zmiennymi zarezerwowanymi w tym środowisku.
Na szczęście istnieje sposób wymagający zasięg globalny i testowania, co to jest - jeśli utworzyć nową funkcję używając new Function()
konstruktor zakres wykonanie this
jest oprawiony w zakresie globalnym i można porównać zasięg globalny bezpośrednio do oczekiwanej wartości.*)
więc stworzyć kontrolę działania, jeżeli zakres globalny to "okno" byłoby
var isBrowser=new Function("try {return this===window;}catch(e){ return false;}");
// tests if global scope is binded to window
if(isBrowser()) console.log("running under browser");
i funkcja aby sprawdzić, czy globalny SopE jest binded do "globalne" byłoby
var isNode=new Function("try {return this===global;}catch(e){return false;}");
// tests if global scope is binded to "global"
if(isNode()) console.log("running under node.js");
the try ... catch -part upewni się, że jeśli zmienna nie zostanie zdefiniowana, zwracana jest nazwa false
.
Można także porównać this.process.title==="node"
lub inną zmienną zakresu globalnego znajdującą się w pliku node.js, ale w porównaniu do wersji globalnej powinno wystarczyć.
http://jsfiddle.net/p6yedbqk/
UWAGA: wykrywanie środowiska bieg nie jest zalecane. Może to jednak być przydatne w specyficznym środowisku, takim jak środowisko programistyczne i testowe, które ma pewne znane cechy globalnego zasięgu.
Teraz - druga część odpowiedzi. po wykryciu środowiska, możesz wybrać strategię opartą na środowisku, której chcesz użyć (jeśli jest), aby powiązać zmienną, która jest "globalna" dla twojej aplikacji.
Zalecana strategia tutaj, moim zdaniem, polegałaby na użyciu pojedynczego wzoru do wiązania ustawień wewnątrz klasy. Nie jest dobrym lista alternatyw już w takim
Simplest/Cleanest way to implement singleton in JavaScript?
więc może okazać się, jeśli nie potrzebujemy zmiennej „globalne” i nie trzeba wykrywania środowiska w ogóle, po prostu użyć wzór singleton do zdefiniowanego modułu, który zapisze wartości dla ciebie. Ok, można argumentować, że sam moduł jest zmienną globalną, która w języku JavaScript tak naprawdę jest, ale przynajmniej teoretycznie wygląda to nieco czystszy sposób robienia tego.
*) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
Uwaga: Funkcje utworzone z konstruktora Function nie tworzą zamknięć do ich kontekstach stworzenia; są zawsze tworzone w globalnym zasięgu . Podczas ich uruchamiania będą mogły uzyskać dostęp tylko do własnych zmiennych lokalnych i globalnych, a nie do tych z zakresu , w których wywołano konstruktor funkcji.
Możliwy duplikat [Jak sprawdzić, czy skrypt jest uruchomiony w węźle .js?] (https://stackoverflow.com/questions/4224606/how-to-check-whether-a-script-is-running-under-node-js) –