Obecnie robię to:

foo.js

const FOO = 5;

module.exports = {
    FOO: FOO
};

I używając go w bar.js:

var foo = require('foo');
foo.FOO; // 5

Czy jest lepszy sposób na to? Czuje się niezręcznie, aby zadeklarować stałą w obiekcie eksportu.

262
Tower 21 grudzień 2011, 23:54

12 odpowiedzi

Najlepsza odpowiedź

Możesz wyraźnie wyeksportować go do globalnego zakresu za pomocą global.FOO = 5. Następnie po prostu musisz wymagać pliku, a nawet nie zapisujesz wartości powrotu.

Ale naprawdę nie powinieneś tego robić. Utrzymywanie rzeczy odpowiednio kapsułek jest dobrą rzeczą. Masz już odpowiedni pomysł, więc robisz, co robisz.

103
Alex Wayne 1 październik 2015, 23:07

Moim zdaniem wykorzystanie Object.freeze pozwala na suszarkę i bardziej deklaratywny styl. Moim preferowanym wzorem jest:

./lib/constants.js

module.exports = Object.freeze({
    MY_CONSTANT: 'some value',
    ANOTHER_CONSTANT: 'another value'
});

./lib/some-module.js

var constants = require('./constants');

console.log(constants.MY_CONSTANT); // 'some value'

constants.MY_CONSTANT = 'some other value';

console.log(constants.MY_CONSTANT); // 'some value'

Przestarzały ostrzeżenie o wydajności

Poniższa kwestia została ustalona w V8 w styczniu 2014 r. I nie jest już istotna dla większości deweloperów:

Bądź świadomy, że oba ustawienia zapisywalne do fałszywego i za pomocą obiektu "NefErer"> https://bugs.chromium.org/p/v8/issues/detail?id=1858 i http://jsperf.com/performance-Frozen-object

353
illiteratewriter 17 luty 2021, 05:34

Technicznie const nie jest częścią specyfikacji ECMAScript. Ponadto, używając wzoru "Commono Module", możesz zmienić wartość tej "stałej", ponieważ jest teraz tylko właściwością obiektową. (Nie jestem pewien, czy to kaskadę jakichkolwiek zmian w innych skryptach, które wymagają tego samego modułu, ale to możliwe)

Aby uzyskać prawdziwą stałą, że można również udostępnić, sprawdzić {{x0} }, Object.defineProperty i Object.defineProperties. Jeśli ustawisz writable: false, nie można zmodyfikować wartości w "stałej". :)

To trochę podawana (ale nawet to można zmienić z małym JS), ale powinieneś tylko zrobić to raz na moduł stałych. Korzystając z tych metod, dowolny atrybut, który opuściłeś domyślnie do false. (W przeciwieństwie do określania właściwości za pośrednictwem przypisania, co domyślne są wszystkie atrybuty do true)

Tak więc, hipotetycznie, możesz po prostu ustawić value i enumerable, pozostawiając writable i configurable, ponieważ domyślnie są false, właśnie włączyłem dla jasności.

Aktualizacja - Stworzę nowy moduł (węzeł stałe) Z funkcjami pomocniczymi dla tego samego użycia.

Constants.js - Dobry

Object.defineProperty(exports, "PI", {
    value:        3.14,
    enumerable:   true,
    writable:     false,
    configurable: false
});

Constants.js - lepiej

function define(name, value) {
    Object.defineProperty(exports, name, {
        value:      value,
        enumerable: true
    });
}

define("PI", 3.14);

Script.js

var constants = require("./constants");

console.log(constants.PI); // 3.14
constants.PI = 5;
console.log(constants.PI); // still 3.14
166
Dominic Barnes 22 grudzień 2011, 00:12

Sposób ES6.

Eksportuj w foo.js

const FOO = 'bar';
module.exports = {
  FOO
}

Importuj w bar.js

const {FOO} = require('foo');
114
Isk1n 10 listopad 2016, 12:46

Znalazłem rozwiązanie Dominic sugerowane jako najlepszy, ale nadal brakuje jednej funkcji deklaracji "Const". Gdy deklarujesz stałą w języku słowowym "Const", istnienie stałej jest sprawdzane w czasie Parse, a nie w czasie wykonywania. Jeśli więc napisałeś nazwę stałą gdzieś później w swoim kodzie, otrzymasz błąd podczas próby uruchomienia programu Node.js. Co jest znacznie bardziej lepszą kontrolą błędów.

Jeśli zdefiniujesz stałą z funkcją zdefiniowaną (), taką jak Dominic Sugerowany, nie otrzymasz błędu, jeśli źle napisałeś stałą, a wartość nieustającego stałej będzie niezdefiniowany (co może prowadzić do debugowania bólów głowy).

Ale myślę, że to najlepsze, co możemy dostać.

Dodatkowo, oto rodzaj poprawy funkcji Dominika, w stelażach:

global.define = function ( name, value, exportsObject )
{
    if ( !exportsObject )
    {
        if ( exports.exportsObject )
            exportsObject = exports.exportsObject;
        else 
            exportsObject = exports;        
    }

    Object.defineProperty( exportsObject, name, {
        'value': value,
        'enumerable': true,
        'writable': false,
    });
}

exports.exportObject = null;

W ten sposób można użyć funkcji zdefiniowania () w innych modułach, a umożliwia zdefiniowanie stałych zarówno wewnątrz modułu Constants.js i stałych wewnątrz modułu, z którego nazywałeś funkcją. Deklarujące stałe modułów można następnie zrobić na dwa sposoby (w skrypcie.js).

Pierwszy:

require( './constants.js' );

define( 'SOME_LOCAL_CONSTANT', "const value 1", this ); // constant in script.js
define( 'SOME_OTHER_LOCAL_CONSTANT', "const value 2", this ); // constant in script.js

define( 'CONSTANT_IN_CONSTANTS_MODULE', "const value x" ); // this is a constant in constants.js module

Druga:

constants = require( './constants.js' );

// More convenient for setting a lot of constants inside the module
constants.exportsObject = this;
define( 'SOME_CONSTANT', "const value 1" ); // constant in script.js
define( 'SOME_OTHER_CONSTANT', "const value 2" ); // constant in script.js

Ponadto, jeśli chcesz, aby określić funkcję definiowania () do nazywania tylko z modułu stałego (nie zamieszanie obiektu globalnego), definiujesz to w ten sposób w stonstants.js:

exports.define = function ( name, value, exportsObject )

I użyj go w ten sposób w script.js:

constants.define( 'SOME_CONSTANT', "const value 1" );
16
xmak 16 luty 2012, 00:23

Z poprzedniego doświadczenia projektu jest to dobry sposób:

W stonstants.js:

// constants.js

'use strict';

let constants = {
    key1: "value1",
    key2: "value2",
    key3: {
        subkey1: "subvalue1",
        subkey2: "subvalue2"
    }
};

module.exports =
        Object.freeze(constants); // freeze prevents changes by users

W Main.js (lub app.js itp.), Użyj go jak poniżej:

// main.js

let constants = require('./constants');

console.log(constants.key1);

console.dir(constants.key3);
13
Manohar Reddy Poreddy 14 sierpień 2017, 09:38

Myślę, że const rozwiązuje problem dla większości ludzi poszukujących tego Anwwera. Jeśli naprawdę potrzebujesz niezmiennej stałej, spójrz na inne odpowiedzi. Aby wszystko zorganizowało, zapiszę wszystkie stałe w folderze, a następnie wymagać całego folderu.

Plik src / main.js

const constants = require("./consts_folder");

Src / consts_folder / index.js

const deal = require("./deal.js")
const note = require("./note.js")


module.exports = {
  deal,
  note
}

ps. Tutaj deal i note będzie pierwszym poziomem na Main.js

SRC / Kontakt Folder / Node.js

exports.obj = {
  type: "object",
  description: "I'm a note object"
}

ps. obj będzie drugim poziomem na Main.js

Src / consts_folder / deal.js

exports.str = "I'm a deal string"

ps. str będzie drugim poziomem na Main.js

końcowy wynik na pliku Main.js:

console.log(constants.deal); Wynik:

{Deal: {str: "M" M "r

console.log(constants.note); Wynik:

Uwaga: {obj: {Type: 'Obiekt', Opis: "M 'm a Uwaga obiekt"}}

8
Luis Martins 8 luty 2018, 16:43

Jako alternatywa, możesz grupować swoje wartości "stałe" w lokalnym obiekcie i wyeksportuj funkcję, która zwraca płytkie klon tego obiektu.

var constants = { FOO: "foo" }

module.exports = function() {
  return Object.assign({}, constants)
}

Wtedy nie ma znaczenia, czy ktoś ponownie przypisuje foo, ponieważ wpłynie to tylko na ich lokalną kopię.

4
herman 23 czerwiec 2016, 10:40

Ponieważ węzeł

3
alessioalex 21 grudzień 2011, 20:03

Skończyło się to zrobić, eksportując zamrożony obiekt z anonimowym funkcjami Gettera, a nie same stałe. Zmniejsza to ryzyko paskudnych błędów wprowadzonych z powodu prostego literówki o nazwie Const, ponieważ błąd środowiska wykonawczego zostanie rzucony w przypadku literówki. Oto pełny przykład, który wykorzystuje również symbole ES6 stałych, zapewniając wyjątkowość i funkcje strzałek ES6. Doceniłoby informacje zwrotne, jeśli coś w tym podejściu wydaje się problematyczne.

'use strict';
const DIRECTORY = Symbol('the directory of all sheets');
const SHEET = Symbol('an individual sheet');
const COMPOSER = Symbol('the sheet composer');

module.exports = Object.freeze({
  getDirectory: () => DIRECTORY,
  getSheet: () => SHEET,
  getComposer: () => COMPOSER
});
3
Eloquence 1 wrzesień 2015, 01:49

Zalecam to z Webpack (zakłada, że używasz WebPack).

Definiowanie stałych jest tak proste jak ustawienie pliku konfiguracyjnego WebPack:

var webpack = require('webpack');
module.exports = {
    plugins: [
        new webpack.DefinePlugin({
            'APP_ENV': '"dev"',
            'process.env': {
                'NODE_ENV': '"development"'
            }
        })
    ],    
};

W ten sposób definiujesz je poza swoim źródłem, a będą dostępne we wszystkich plikach.

0
galki 22 czerwiec 2016, 03:31

Nie sądzę, by dobra praktyka do wywołania globalnej przestrzeni z modułów, ale w scenariuszach, gdzie może być ściśle niezbędne do wdrożenia:

Object.defineProperty(global,'MYCONSTANT',{value:'foo',writable:false,configurable:false});

Musi być uważany za wpływ tego zasobu. Bez odpowiedniej nazewnictwa tych stałych, ryzyko nadpisania już zdefiniowanych zmiennych globalnych, jest czymś prawdziwym.

0
colxi 15 sierpień 2017, 20:25