If so, what is the syntax for such a declaration?
Javascript doesn't really have the notion of a named constant, or an immutable property of an object. (Note that I'm not talking about ES5 here.)
You can declare globals with a simple var declaration in the global scope, like outside any function in a script included by a web page:
<script>
var EXACTLY_ONE = 1;
Then your code can use that constant of course, though it's not really "constant" because the value can be changed (the property updated, in other words).
edit — this is an ancient answer to an ancient question. In 2019, there's the const declaration that's supported just about everywhere. However note that like let, const scoping is different from var scoping.
As "Pointy" so carefully notes, ECMAscript has no such feature. However, JavaScript does:
const a = 7;
document.writeln("a is " + a + ".");
Of course, if you're writing code to put on the web to run in web browsers, this might not help you much. :-)
Everything is global unless declared with the var keyword.
There are no constants either. You can simply declare them without the var keyword.
If you want to ensure global scope you can throw it into the window object:
window.GLOBAL_CONSTANT = "value";
You can do this from within any scope. Constants can then be declared inside functions or closures, though I wouldn't recommend that.
If you only care about supporting newer browsers (or are using a transpiler such as Babel to support older browsers) you can do the following:
Create a settings.js file with whatever constants you want and export them:
export const FRUIT = "kiwi";
export const VEGETABLE = "carrot";
In files that you want to use them you could then import them as follows:
import * as Settings from './settings.js'
Then to use the constants do something like this:
console.log("The unchangeable fruit is " + Settings.FRUIT);
This is a much cleaner approach than trying to implement a global constant, especially when you have multiple JavaScript files that you want to use the constants in.
You could do it with getters and setters like so:
Object.defineProperty(window, 'TAU', {
get: function(){return Math.PI*2;}
});
If you want a general function to do this:
function define(name, value){
Object.defineProperty(window, name, {
get: function(){return value;},
set: function(){throw(name+' is a constant and cannot be redeclared.');},
});
}
// Example use
define('TAU', Math.PI*2);
If you want to make sure the value cannot change use a function.
So, instead of:
var Const_X=12
use:
function Const_X() {
return 12;
}
The direct answer to the question is No. It would really help though if ECMA/JS made a way to easily do functional programming. A workable hack I use to get around this is to declare a const in the global scope and use a wrapper function see example below:
:)
global_var = 3; //This can change say inside a function etc. but once you decide to make
//this global variable into a constant by calling on a function
const make_variable_constant = function(variable)
{
const constant = variable;
return constant;
}
const const_global = make_variable_constant(global_var);
:)
Way back when object oriented programming was the hype a kid in my class told the C instructor that C isn't object oriented to which the instructor said he's done object oriented programming in C before Java and C++ were even conceived. Likewise you can do functional programming in Javascript but its much harder. Its like doing Object-oriented programming in C when its easier to do it in C++.
For the record.
// ES6+ code:
const CONSTGLOBAL1=200; // it is a constant global
function somef() {
document.write(CONSTGLOBAL1); // CONSTGLOBAL1 is defined (because it's global)
const CONSTLOCAL=200; // it's a local constant
document.write(CONSTLOCAL); // CONSTLOCAL is defined
}
somef();
document.write(CONSTLOCAL); // CONSTLOCALis NOT defined.
So, if the constant is defined inside {} then it's local, otherwise, it's global.
Similar to kojow7's answer, but instead of using grabbing all named exports I like to use one named export e.g. Constants and then declare my constants like this:
Create a Constants.js file with declaring your constants like this and export Constants:
// Constants.js
export const Constants = {
FRUIT: "kiwi",
VEGETABLE: "carrot",
};
Make a named import in the files you need a constant:
import { Constants } from './Constants';
Then use the constants as follows:
console.log("The unchangeable fruit is " + Constants.FRUIT);
There seems to be no downfall to use the one over the other option, but what I like personally is that I just name the file as I want to import it import { Constants } from './Constants'; and not always think about how I call it when grabbing all named exports import * as Constants from './Constants'. So in the second case I might want to look in another file where I imported already the constants and look how I named the import in case of consistency. Have a look also here for the different export/import possibilities.
If you're not planning to change the value of any object properties, you can use Object.freeze():
window.globalConst = Object.freeze( { x: 1, y: true } );
The following demonstrates the difference between const and Object.freeze():
const x = Object.freeze({
a: 1,
b: 2
});
x.a = 3;
// x.a is still = 1
console.log("x.a = ", x.a);
const y = {
a: 1,
b: 2
};
y.a = 3;
// y.a has been changed to 3
console.log("y.a = ", y.a);
Related
i want to understand a little bit more about the javascript reference scope, i was trying to import a function from onother file like this
file1.js
exports.checkIfCan = function(){
//make some check
}
exports.calculate = function(){
this.checkIfCan();
}
and using the calculate method with this import
file2.js
const { calculate } = require('./file1.js')
calculate()
actually the error is this.checkIfCan is not a function
but if i import all the module like this it works
const calculation = require('./file1.js')
calculation.calculate();
I just wanna understand more about the global/local scope in javascript
this refers to the context of the function invocation, which in your case is undefined (on browsers the default is window).
Here's an example as simple as possible to make you understand it:
calculation.calculate(); // <= you are calling calculate from calculation, so 'this' is calculation
calculate(); // <= you are calling calculate from... nothing, so 'this' is undefined
Update: using arrow functions it would work either case because this will be taken from the function's surrounding scope instead of the context, and in the top-level code in a Node module this is equivalent to module.exports.
There's a lot to explain about the thisin javascript, may I suggest you read the free ebook You Don't Know JS: this and Object prototypes? You'll find much more information there.
#Vlad Vlads, your problem is in the use of keyword this in your file file file1.js.
In accordance to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this, following behaviour may happen:
The value of this is determined by how a function is
called (runtime binding). It can't be set by assignment during
execution, and it may be different each time the function is called.
With that been said, if you remove the keyword this in your function, following will then works as expected:
const { calculate } = require('./file1.js')
calculate()
Your second example will also works as expected
const calculation = require('./file1.js')
calculation.calculate()
You should use import instead:
file1.js
function abc() {}
export {
abc
}
file2.js
import { abc } from 'file1.js';
abc();
I am a big fan of latest programming conventions and latest additions to programming languages. Recently I read in Google Guidelines that we should use const and let instead of var.
Now in my project I have namespace object variables (if that's what they are called, correct me please if I am wrong) like this
var myObj = {
func1: {},
func2: {}
};
var myOtherObj = {
var1: 'foo',
var2: 'bar'
};
How should I name these objects now using the new conventions, with const or with let? I am confused because I don't know if these big objects change over time, or not...
const doesn't prevent objects from changing (said otherwise it doesn't freeze them). It prevents the value of variables to change.
For example you can still do
const myObj = {
func1: {},
func2: {}
};
and then
myObj.fun3 = function(){...
What you can't do with a variable declared with const (but which doesn't seem to be your will) is
myObj = {};
Modules are usually declared with const.
The general rule I try to follow is: const everywhere you can, let when you can't use const and var never.
In the case of your example, when you are defining objects (or in other cases arrays, etc.), I tend to define those with let to give a clear indication that either the variable reference could change or the contents inside.
const will not prevent properties of objects or elements in a list from being changed, so if you're unsure if thats going to happen, its best to use let in my opinion. It's more clear and could prevent confusion down the road.
If you really want a symbol that can't change value to refer to an object that is also immutable, you can do this:
const CONSTANT = Object.freeze({
a: "hello",
b: "world"
});
Also bear in mind that older platforms are still out there that won't support const and let (and probably Object.freeze() for that matter).
In typescript I can import another module\namespace like so:
namespace Shapes2 {
import shapes = Shapes;
var bar = new shapes.Bar();
}
However, I can just as easily refer to the namespace directly.
namespace Shapes3{
var shapes = Shapes;
var bar = new shapes.Bar();
}
Is import doing anything useful?
When would I want to type import rather than var?
In that specific case, no it's not doing anything useful. That syntax is for creating aliases for namespaces. Your example would be more useful in a situation like this:
namespace Shapes2 {
import Rects = Shapes.Rectangles;
var bar = new Rects.Red();
// Instead of `var bar = new Shapes.Rectangles.Red()`
}
Basically, it's just a way of reducing the amount of typing you do. In a way, it's a substitution for using in C#. But how does this differ from var?
This is similar to using var, but also works on the type and namespace meanings of the imported symbol. Importantly, for values, import is a distinct reference from the original symbol, so changes to an aliased var will not be reflected in the original variable.
source
A good example of this can be found in the spec:
namespace A {
export interface X { s: string }
}
namespace B {
var A = 1;
import Y = A;
}
'Y' is a local alias for the non-instantiated namespace 'A'. If the declaration of 'A' is changed such that 'A' becomes an instantiated namespace, for example by including a variable declaration in 'A', the import statement in 'B' above would be an error because the expression 'A' doesn't reference the namespace instance of namespace 'A'.
When an import statement includes an export modifier, all meanings of the local alias are exported.
From the TypeScript Handbook
Another way that you can simplify working with of namespaces is to use import q = x.y.z to create shorter names for commonly-used objects. Not to be confused with the import x = require("name") syntax used to load modules, this syntax simply creates an alias for the specified symbol. You can use these sorts of imports (commonly referred to as aliases) for any kind of identifier, including objects created from module imports.
I am trying to have some const global variables which I can use in the javascript and I came out with this code and picking up from some answers referred in SO. But it seems that I have a little mistake somewhere which I couldn't spot. Can someone help me with this?
in testQuery.js
(function (window, undefined) {
var testQuery = function(obj) {
if (!(this instanceof testQuery)) {
return new testQuery(obj);
}
}
var MYGLOBALS = function() {
var globals = {
foo : "bar",
batz : "blah"
}
return {
getValue : function(s) {
return globals[s];
}
}
}();
window.testQuery = testQuery;
}) (window);
and in the html javascript tag i have this line of code.
in testQuery.html file
<html>
<head>
<script src="testQuery.js"></script>
<script>
function onClick() {
alert(MYGLOBALS.getValue("foo"));
}
</script>
</head>
<body>
<input type="button" onclick="onClick()">
</body>
</html>
The variable MYGLOBALS is local to your scoping function (the big outermost function that has no name), so it can only be accessed from within that function.
I'm not sure what you mean by "...in the html javascript tag..." but if the alert you've quoted is outside that scoping function, MYGLOBALS is out of scope for it.
Update: The thing about JavaScript scope is that it's much simpler than people think it is. Variables declared with var are private to the scope (function or global; JavaScript has no block-level scope so just {} doesn't do it) in which they're declared, and sub-scopes of that scope (e.g., functions declared or define within it). And scope is entirely lexical — that is, it is what you see in the source code, not dictated by some other runtime structure. They don't pop out of that scope unless you see code somewhere explicitly making that happen, as with your window.testQuery = testQuery; line, which explicitly makes testQuery a property on window and therefore a global variable. (And even then, it's not that the variable has popped out of the scope, just that you've created a new property referring to the same thing which is more broadly-accessible.)
Update 2: Re your comment
Actually what I am trying to do is to create something like what you would see when you are doing programming in other language where there will be a final static integer which you can put into the parameters fields on the functions you call. is there a better way of doing it? For example, in visual basic its something like me.background = Color.YELLOW. what I want is to have a static variable which will represent that YELLOW color.
JavaScript doesn't have user-defined constants, and doesn't have enums. (Update: Both of those things may change with ES6.) What you do instead is define an object with the properties, e.g.:
var COLORS = {
RED: "#FF0000",
BLUE: "#0000FF",
// ...
GREEN: "#00FF00"
};
Those aren't constants, there's nothing to keep anyone from assigning to COLORS.RED except your telling them not to.
(Update: In ES5, we can make those properties constant using Object.defineProperties, like this:
var COLORS = Object.defineProperties({}, {
RED: {value: "#FF0000"},
BLUE: {value: "#0000FF"},
// ...
GREEN: {value: "#00FF00"}
});
When you define a property that way, by default it's not writable.)
For what you're doing, you probably want the module pattern, where you have a single global symbol whose value is an object, and everything else is properties on that object:
(function() {
var mod;
// Create the global, and also give ourselves a convenient alias for it (`mod`)
window.MyModule = mod = {};
// Colors
mod.COLORS = {
RED: "#FF0000",
BLUE: "#0000FF",
// ...
GREEN: "#00FF00"
};
mod.testQuery = MyModule_testQuery;
function MyModule_testQuery() {
// Do something
}
})();
alert(MyModule.COLORS.RED); // #FF0000
MyModule.testQuery(); // Do something
Or if you prefer, that testQuery function could be defined like this:
mod.testQuery = function() {
// Do something
};
...but then the function is anonymous, and I'm not a fan of anonymous functions. (Note that there's nothing special about the name MyModule_testQuery, that's purely my naming convention.)
Somewhat off topic:
Regarding this line where we're publishing our global symbol above:
// Create the global, and also give ourselves a convenient alias for it (`mod`)
window.MyModule = mod = {};
Note that that is very specific to browser environments. We could make it applicable to any JavaScript environment with a trivial change:
// Create the global, and also give ourselves a convenient alias for it (`mod`)
this.MyModule = mod = {};
That works because we're the ones who call the outermost scoping function, and so we know that we're not calling it with any particular this value (this in JavaScript — unlike some other languages — is determined entirely by how a function is called, not where or how it's defined). So since we know we're not using any special this value, we know that it will be the global object, because that's how JavaScript works. And the global object is window on web browsers (effectively; technically window is a property on the global object that refers back to itself).
http://jsfiddle.net/vXu7m/1/
Some syntactic cleanup, and attaching you MYGLOBALS to the window object should do what you want.
I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.
If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?
I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
No one should yell at you for doing something like the above.
To make a variable calculated in function A visible in function B, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling B from A.
If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Consider using namespaces:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
Both local_function and global_function have access to all local and global variables.
Edit: Another common pattern:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.
What you're looking for is technically known as currying.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.
I found this to be extremely helpful in relation to the original question:
Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
If another function needs to use a variable you pass it to the function as an argument.
Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.
If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.
Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...
Douglas Crockford wrote:
Jul 15 '06
"If you want to retrieve objects by id, then you should use an object, not an
array. Since functions are also objects, you could store the members in the
function itself."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"The object can be obtained with"
objFacility.wlevine
The objects properties are now accessable from within any other function.
I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.
Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.
You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).
Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):
How to get a variable returned across multiple functions - Javascript/jQuery