Jak tworzyć stałe Javascript jako właściwości obiektów za pomocą słowa kluczowego const?
Dlaczego stałe nie mogą być ustawiane jako właściwości obiektów, które same są zmiennymi?
const a = 'constant' // all is well
// set constant property of variable object
const window.b = 'constant' // throws Exception
// OR
var App = {}; // want to be able to extend
const App.goldenRatio= 1.6180339887 // throws Exception
I dlaczego stałe przekazywane przez odniesienie nagle stają się zmienne? EDIT: wiem, że aplikacja nie będzie (a raczej... Nie powinien) być zmienny; to tylko obserwacja...
(function() {
const App;
// bunch of code
window.com_namespace = App;
}());
window.com_namespace; // App
window.com_namespace = 'something else';
window.com_namespace; // 'something else'
Jak można stworzyć ładnie zorganizowaną, rozszerzalną, zorientowaną obiektowo bibliotekę z pojedynczą przestrzenią nazw zawierającą stałe z tymi ograniczeniami?
EDIT: wierzę zi42, ale muszę zapytać dlaczego
5 answers
Nie można tego zrobić ze stałymi. Jedynym możliwym sposobem zrobienia czegoś, co zachowuje się tak, jak chcesz, ale nie używa stałych, jest zdefiniowanie nie-zapisywalnej właściwości:
var obj = {};
Object.defineProperty( obj, "MY_FAKE_CONSTANT", {
value: "MY_FAKE_CONSTANT_VALUE",
writable: false,
enumerable: true,
configurable: true
});
Jeśli chodzi o twoje pytanie, Dlaczego const
przekazywana do funkcji staje się zmienną, odpowiedź brzmi, ponieważ jest przekazywana przez wartość, a nie przez odniesienie. Funkcja otrzymuje nową zmienną, która ma taką samą wartość jak stała.
Edit : dzięki @pst za Zauważenie, że obiekty w javascript nie jest w rzeczywistości "przekazywany przez odniesienie", ale za pomocą call-by-sharing :
Chociaż termin ten jest szeroko stosowany w społeczności Pythona, identyczna semantyka w innych językach, takich jak Java i Visual Basic, jest często opisywana jako call-by-value, gdzie wartość jest sugerowana jako odniesienie do obiektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-01 02:37:09
const person = {
name: "Nicholas"
};
// works
person.name = "Greg";
console.log(person) //Greg
Dlatego użyj obiektu.defineProperty
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-02 03:19:54
Jest na to znacznie prostszy sposób. Podoba mi się ten wzór. Proste Obiekty.
window.Thingy = (function() {
const staticthing = "immutable";
function Thingy() {
let privateStuff = "something";
function get() {
return privateStuff;
}
function set(_) {
privateStuff = _;
}
return Object.freeze({
get,
set,
staticthing
});
}
Thingy.staticthing = staticthing;
return Object.freeze(Thingy);
})();
let myThingy = new Thingy();
Thingy.staticthing = "fluid";
myThingy.staticthing = "fluid";
console.log(Thingy.staticthing); // "immutable"
console.log(myThingy.staticthing); // "immutable"
Obiekt.freeze robi tu robotę
Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
Jeśli chcesz, możesz zostawić statyczną właściwość poza instancją, pozostawiając ją poza obiektem dosłownym zwrotem w funkcji konstruktora.
Const uczyni go tylko referencją tylko do odczytu. Jak tylko go przypiszesz, jak tutaj w sensie dosłownym obiekt staje się własnością konstruowanego obiektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-15 10:10:25
Nie należy zapominać o const declaration "tworzy odniesienie tylko do odczytu do wartości. Nie oznacza to, że posiadana wartość jest niezmienna, tylko, że identyfikator zmiennej nie może być ponownie przypisany "
Słowo kluczowe const działa w podobny sposób niż 'let' , więc można je ponownie zgłosić w innym bloku
const MyConst = 5;
console.log('global MyConst =', MyConst); //global MyConst = 5
if(true){
const MyConst = 99
console.log('in if block, MyConst =', MyConst); //in if block, MyConst = 99
}
console.log('global MyConst still 5 ?', MyConst===5); //global MyConst still 5 ? true
Tak jak @ziad - saab jeśli chcesz mieć właściwość obiektu niż działać jak stała, musisz zdefiniować ją jako właściwość nie do zapisania.
Jeśli twój stała jest obiektem i właściwość nie powinna się zmieniać, należy użyć obiektu .freeze () Aby obiekt stał się niezmienny.
(function(){
var App = { };
// create a "constant" object property for App
Object.defineProperty(App , "fixedStuff", {
value: Object.freeze({ prop:6 }),
writable: false,
enumerable: true,
configurable: true
});
Object.defineProperty(window, "com_namespace", {
value: App,
writable: false,
enumerable: true,
configurable: true
});
})()
com_namespace.newStuff = 'An extension';
com_namespace.fixedStuff.prop = 'new value'; // do nothing!
console.log(com_namespace.fixedStuff.prop); //6
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-04 16:39:08
var obj = {};
Object.defineProperty( obj, "MY_FAKE_CONSTANT", {
value: "MY_FAKE_CONSTANT_VALUE",
writable: false,
enumerable: true,
configurable: false // instead of true
});
Powinniśmy ustawić również konfigurowalne na fałsz Aby zapobiec usunięciu własności z obj
delete obj.MY_FAKE_CONSTANT;
Z konfigurowalnym aby być prawda, po linii nie mamy już MY_FAKE_CONSTANT.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-09 15:58:00