Use of const in a Javascript class - javascript

In my JS component class, I have the following code at the top;
const {
getOwner
} = Ember;
What exactly does it mean ? Is the purpose to avoid code repetition ?

This is a new feature of JS present in ES6.
This is known as object destructure.
If you have an object like this.
const obj = { name: 'Stack Overflow' };
const { name } = obj;
console.log(name);
You can take a reference ->
Here for Destructure
And yeah about the const keyword.
The const keyword is used to declare a constant variable which is going to be same for the whole
and for const -> Here
try{
const a = 10;
a =12;
}catch(e){
console.log(e);
}

Is the purpose to avoid code repetition.
I don't really think so.
It is just a destructing assignment to assign Ember object's getOwner property to variable getOwner in your code. And const is there to make sure it is not overwritten by some other assignment

Related

JS Proxy & destructuring assignment

As what i know js Proxies make possible to overload classic object getter with a function call.
So that we can do things like that :
const value = myProxy.value;
All that calling in fact the value getter function inside Proxy.
My question is ... is there a way to use the JS destructuring syntax with JS Proxies ?
So that we could do things like that :
const { value } = myProxy;
Based on my tests, the second way is not working.
It is working with a necessary implemented getter.
const
myProxy = new Proxy({}, {
get: function(obj, prop) {
return 42;
}
}),
{ value } = myProxy;
console.log(myProxy.value);
console.log(value);

Set the scope of an eval

Is there a way to set the global of an eval? I would like to set the global of an eval so I don't have to prefix everything with obj.
If I do the following, I get an error
ReferenceError: MyClass is not defined
let obj = {
MyClass: class MyClass {
static CallMe() {}
}
}
eval(`
'use strict';
global = obj;
result = MyClass.CallMe();
`)
However, If I do this:
result = obj.MyClass.CallMe();
It works, but I would like to make it so I don't have to prefix the call with obj. Is there any why that this can be done?
I can't imagine why you need to use eval here, but if you do, you can use with (obj) in your evaluated code:
eval(`
'use strict';
with (obj) {
result = MyClass.CallMe();
}
`);
I still feel like you shouldn't be using eval here (what use is it?), as it's easy to accidentally open yourself to injection vulnerabilities if you're not careful. What are you using eval for here? Maybe we can point out a better way.
Others have warned you already about the risks of using evalso I won't be doing that myself.
I certainly found some legitimate use cases for eval in a controlled environment. I am assuming that you know what you're doing.
This may or may not be useful:
let obj1 = {
foo: () => console.log('scope: obj1')
};
let obj2 = {
foo: () => console.log('scope: obj2')
};
const scopedEval = (context, code) =>
new Function('global', code)(context, code);
scopedEval(obj1, `
global.foo();
`)
scopedEval(obj2, `
global.foo();
`)
Have no idea why you'd like to use eval, especially in such weird way but this might be something that you are looking for:
class MyClass {
static CallMe() {
return 'sample';
}
}
eval(`
'use strict';
let result = MyClass.CallMe();
console.log(result);
`)

How do I expose data from within ES6 blocks?

ES6 has introduced block scopes using let and const. What's the correct way to export data from within the block scope, so that I can access it from outside. Using IIFE you could just assign a the expression to a variable.
{
const add = (a, b) => a+b
// export add?
}
Using export within the block throws an error.
'import' and 'export' may only appear at the top level
One way I've found is to assign it to the global window object
{
const add = (a, b) => a+b
window.add = add
}
I'm just curious to know what the suggested way to do this is?
Create a function, and return the value you need.
const Add = () => {
return 'function add returned...';
};
You can also create a variable outside of the block and just assign it a value inside the block.
let myVar;
const myFunc = () => {
myVar = 'foo';
};

How to check that ES6 "variable" is constant?

Does anyone know some tricks how to do it? I tried to use try-catch:
"use strict";
const a = 20;
var isConst = false;
try {
var temp = a; a = a+1; a = temp;
} catch (e) {
isConst = true;
}
But unfortunately it works only in "strict" mode. Without "use strict" it perform all statements silently, without modification of a. Also I cannot wrap this code into some handy function (isConstant(someConst) for example) as any argument I'll pass to that function will be a new variable. So anyone know how to create isConstant() function?
I don't think there is, but I also don't think this is a big issue. I think it might be useful to have the ability to know if a variable is const, and this exists in some other languages, but in reality since you (or someone on a team) will be defining these variables, you'd know the scope and the type of the variables. In other words, no you can't, but it's also not an issue.
The only case where it might be useful is if you could change the mutable property during runtime, and if changing this property had actual performance benefits; let, const, and var are treated roughly equally to the compiler, the only difference is that the compiler keeps track of const and will check assignments before it even compiles.
Another thing to note is that just like let, const is scoped to the current scope, so if you have something like this:
'use strict';
const a = 12;
// another scope
{
const a = 13;
}
it's valid. Just be careful that it will look up in higher scopes if you don't explicitly state const a = 13 in that new scope, and it will give a Read Only or Assignment error:
'use strict';
const a = 12;
{
a = 13; // will result in error
}
Based on some of the answers here I wrote this code snippet (for client side JS) that will tell you how a "variable" was last declared--I hope it's useful.
Use the following to find out what x was last declared as (uncomment the declarations of x to test it):
// x = 0
// var x = 0
// let x = 0
// const x = 0
const varName = "x"
console.log(`Declaration of ${varName} was...`)
try {
eval(`${varName}`)
try {
eval(`var ${varName}`);
console.log("... last made with var")
} catch (error) {
try {
eval(`${varName} = ${varName}`)
console.log("... last made with let")
} catch (error) {
console.log("... last made with const")
}
}
} catch (error) {
console.log("... not found. Undeclared.")
}
Interestingly, declaring without var, let or const, i.e x = 0, results in var getting used by default. Also, function arguments are re-declared in the function scope using var.
Just check if your reassignment actually did something:
var isConst = function(name, context) {
// does this thing even exist in context?
context = context || this;
if(typeof context[name] === "undefined") return false;
// if it does exist, a reassignment should fail, either
// because of a throw, or because reassignment does nothing.
try {
var _a = context[name];
context[name] = !context[name];
if (context[name] === _a) return true;
// make sure to restore after testing!
context[name] = _a;
} catch(e) { return true; }
return false;
}.bind(this);
You need the try/catch because reassign Could throw an exception (like in Firefox), but when it doesn't (like in Chrome), you just check whether your "this always changes the value" reassignment actually did anything.
A simple test:
const a = 4;
var b = "lol";
isConst('a'); // -> true
isConst('b'); // -> false
And if you declare the consts in different context, pass that context in to force resolution on the correct object.
downside: this won't work on vars declared outside of object scopes. upside: it makes absolutely no sense to declare them anywhere else. For instance, declaring them in function scope makes the const keyword mostly useless:
function add(a) {
return ++a;
}
function test() {
const a = 4;
console.log(add(a));
}
test(); // -> 5
Even though a is constant inside test(), if you pass it to anything else, it's passed as a regular mutable value because it's now just "a thing" in the arguments list.
In addition, the only reason to have a const is because it does not change. As such, constantly recreating it because you're calling a function that makes use of it more than once, means your const should live outside the function instead, so again, we're forced to put the variable in an object scope.
The question refers to incompliant behaviour in earlier ES6 implementations, notably V8 (Node.js 4 and legacy Chrome versions). The problem doesn't exist in modern ES6 implementations, both in strict and sloppy modes. const reassignment should always result in TypeError, it can be caught with try..catch.
There can't be isConstant function because const variable cannot be identified as such by its value.
It's preferable to run a script in strict mode and thus avoid problems that are specific to sloppy mode.
Even if a variable was defined in sloppy mode, it's possible to enable strict mode in nested function scope:
const foo = 1;
// ...
let isConst = false;
(() => {
'use strict';
try {
const oldValue = foo;
foo = 'new value';
foo = oldValue;
} catch (err) {
isConst = true;
}
})();
It's beneficial to use UPPERCASE_CONSTANT convention which is used in JavaScript and other languages. It allows to unambiguously identify a variable as a constant without aid from IDE and avoid most problems with accidental reassignments.

Javascript: constant properties

In javascript, can I declare properties of an object to be constant?
Here is an example object:
var XU = {
Cc: Components.classes
};
or
function aXU()
{
this.Cc = Components.classes;
}
var XU = new aXU();
just putting "const" in front of it, doesn't work.
I know, that i could declare a function with the same name (which would be also kind of constant), but I am looking for a simpler and more readable way.
Browser-compatibility is not important. It just has to work on the Mozilla platform, as it is for a Xulrunner project.
Thank you a lot!
Cheers.
Since you only need it to work on the Mozilla platform, you can define a getter with no corresponding setter. The best way to do it is different for each of your examples.
In an object literal, there is a special syntax for it:
var XU = {
get Cc() { return Components.classes; }
};
In your second exampe, you can use the __defineGetter__ method to add it to either aXU.prototype or to this inside the constructor. Which way is better depends on whether the value is different for each instance of the object.
Edit: To help with the readability problem, you could write a function like defineConstant to hide the uglyness.
function defineConstant(obj, name, value) {
obj.__defineGetter__(name, function() { return value; });
}
Also, if you want to throw an error if you try to assign to it, you can define a setter that just throws an Error object:
function defineConstant(obj, name, value) {
obj.__defineGetter__(name, function() { return value; });
obj.__defineSetter__(name, function() {
throw new Error(name + " is a constant");
});
}
If all the instances have the same value:
function aXU() {
}
defineConstant(aXU.prototype, "Cc", Components.classes);
or, if the value depends on the object:
function aXU() {
// Cc_value could be different for each instance
var Cc_value = return Components.classes;
defineConstant(this, "Cc", Cc_value);
}
For more details, you can read the Mozilla Developer Center documentation.
UPDATE: This works!
const FIXED_VALUE = 37;
FIXED_VALUE = 43;
alert(FIXED_VALUE);//alerts "37"
Technically I think the answer is no (Until const makes it into the wild). You can provide wrappers and such, but when it all boils down to it, you can redefine/reset the variable value at any time.
The closest I think you'll get is defining a "constant" on a "class".
// Create the class
function TheClass(){
}
// Create the class constant
TheClass.THE_CONSTANT = 42;
// Create a function for TheClass to alert the constant
TheClass.prototype.alertConstant = function(){
// You can’t access it using this.THE_CONSTANT;
alert(TheClass.THE_CONSTANT);
}
// Alert the class constant from outside
alert(TheClass.THE_CONSTANT);
// Alert the class constant from inside
var theObject = new TheClass();
theObject.alertConstant();
However, the "class" TheClass itself can be redefined later on
If you are using Javascript 1.5 (in XUL for example), you can use the const keyword instead of var to declare a constant.
The problem is that it cannot be a property of an object. You can try to limit its scope by namespacing it inside a function.
(function(){
const XUL_CC = Components.classes;
// Use the constant here
})()
To define a constant property, you could set the writable attribute to false in the defineProperty method as shown below:
Code snippet:
var XU = {};
Object.defineProperty(XU, 'Cc', {
value: 5,
writable: false
});
XU.Cc = 345;
console.log(XU.Cc);
Result:
5 # The value hasn't changed

Categories

Resources