I wanted to shorten an object literal in ES6 like this:
const loc = this.props.local;
The reason is loc.foo(); is a lot easier to type than this.props.local.foo();
But now ESLint complains:
Use object destructuring: prefer-destructuring
I've read the error description on eslint.org but I don't understand it. They have an example which looks very similar to my code but theirs seem to be ok?
var foo = object.bar;
How can I fix the error without setting it to ignore in the .eslintrc file?
change your code from:
const local = this.props.local;
to:
const { local } = this.props;
They are equivalent and you can call local.foo() in the same way. except that the second use object destructuring.
It's a new construct in ES 6 that allows you to match property of an object in assignment. The syntax you need is:
const { local: loc } = this.props
which translates to: "declare a constant loc and assign it the value of property local from this.props".
It's telling you to use
const {props: {local: loc}} = this;
Related
I keep seeing functions that look like this in a codebase I'm working on:
const func = ({ param1, param2 }) => {
//do stuff
}
What exactly is this doing? I'm having a hard time finding it on google, because I'm not even sure what this is called, or how to describe it in a google search.
It is destructuring, but contained within the parameters. The equivalent without the destructuring would be:
const func = o => {
var param1 = o.param1;
var param2 = o.param2;
//do stuff
}
This is passing an object as a property.
It is basically shorthand for
let param1 = someObject.param1
let param2 = someObject.param2
Another way of using this technique without parameters is the following, let's consider then for a second that someObject does contain those properties.
let {param1, param2} = someObject;
It is an object destructuring assignment. Like me, you may have found it surprising because ES6 object destructuring syntax looks like, but does NOT behave like object literal construction.
It supports the very terse form you ran into, as well as renaming the fields and default arguments:
Essentially, it's {oldkeyname:newkeyname=defaultvalue,...}. ':' is NOT the key/value separator; '=' is.
Some fallout of this language design decision is that you might have to do things like
;({a,b}=some_object);
The extra parens prevent the left curly braces parsing as a block, and the leading semicolon prevents the parens from getting parsed as a function call to a function on the previous line.
For more info see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
Beware, key errors during object destructuring assignment do NOT throw; you just end up with "undefined" values, whether it's a key error or some other error that got silently propagated as 'undefined'.
> var {rsienstr: foo, q: bar} = {p:1, q:undefined};
undefined
> foo
undefined
> bar
undefined
>
I've been using and loving babel (6.5.2) for a while now and find the new destructuring syntax great for writing clearer JavaScript.
Why doesn't the rest destructuring work (it generates a token error) anywhere in the array?
For example:
const [column, ...restOfColumns] = columns;
const objProps = column.valueChain.slice(0, -1);
const prop = column.valueChain[column.valueChain.length - 1];
//const [...objProps, prop] = column.valueChain
The commented out line would replace the preceding two lines with something much easier to read and understand.
The simple answer is that when you use the destructing syntax ..., it means everything else. Therefore when you try [...objProps, prop], it doesn't know what to assign to prop as you have assigned all values already to objProps
I have this code here:
getData(value, index) {
const {responseMetadata, responseData} = this.getResponseDatum();
return responseData.get(index).get('code').toUpperCase();
}
eslint reports an error:
19:12 "responseMetadata" is defined but never used
In python I can silent this kind of error by renaming the variable to _responseMetadata. Is there a Equivalent in es6?
If you don't need the variable, just don't create it:
const {responseData} = this.getResponseDatum();
A destructuring assignment doesn't need to match all properties of the returned object.
In your case, since you need only one property and don't use it multiple times, there's actually not much reason to use destructuring or a variable at all:
getData(value, index) {
return this.getResponseDatum().responseData.get(index).get('code').toUpperCase();
}
You can turn off a rule for a section of code. See http://eslint.org/docs/user-guide/configuring.html#configuring-rules
/*eslint-disable */
//suppress all warnings between comments
alert('foo');
/*eslint-enable */
I was hoping that typescript maybe able to detect when a function could return an undefined value and warn me. I tried the following but the playground editor on typescript site did not show any warnings
class Test {
get(key: string) :string{
var hash = {'some-key': 1, 'some-other-key': 3};
return hash[key]
}
}
Is it possible to get typescript to warn when a function could sometimes return a undefined value when you explicitly stated that it should only return some particular type?
TypeScript doesn't check the existence of the property when you use hash[key] as it would when you use hash.myKey. So to get design-time and compile-time checking you would have to change the way you expose this information to allow the code to use the dot-property syntax...
So instead of:
class Test {
get(key: string) :string{
var hash = {'some-key': 1, 'some-other-key': 3};
return hash[key];
}
}
var test = new Test();
test.get('myKey');
You could expose:
class Test {
public hash = { someKey: 1, someOtherKey: 3};
}
var test = new Test();
test.hash.myKey; // you'll get a warning here
This only works if this design is appropriate for what you are doing - but you'll get the warnings doing things this way as TypeScript will create an anonymous type for hash and will ensure only known properties are used.
Update: I updated the examples based on feedback. It is worth noting that although using 'some-key' prevents you from using dot-notation (so it is definitely worth dropping the hyphen if you can) - you will still get code-completion.
It might not stop you from accidentally returning undefined, but your code definitely returns undefined as proven by:
class Test {
get(key: string) :string{
var hash = {'some-key': 1, 'some-other-key': 3};
return hash[key]
}
}
var test = new Test();
alert(test.get("asdf"));
TypeScript would need to support something like CodeContracts to do what you are asking.
As Steve mentioned you can use property access (.) instead of index access ([string]). But that will work only if your properties follow typescript naming conventions. i.e. property names cannot contain '-' e.g. the following works:
class Test {
public hash = {'someKey': 1, 'someOtherKey': 3};
}
var test = new Test();
test.hash.someKey;// Valid
test.hash.myKey; // you'll get a warning here
This question already has answers here:
Are there constants in JavaScript?
(33 answers)
Closed 6 years ago.
I want to declare string constants in JavaScript.
Is there is a way to do that?
Many browsers' implementations (and Node) have constants, used with const.
const SOME_VALUE = "Your string";
This const means that you can't reassign it to any other value.
Check the compatibility notes to see if your targeted browsers are supported.
Alternatively, you could also modify the first example, using defineProperty() or its friends and make the writable property false. This will mean the variable's contents can not be changed, like a constant.
Are you using JQuery? Do you want to use the constants in multiple javascript files? Then read on. (This is my answer for a related JQuery question)
There is a handy jQuery method called 'getScript'. Make sure you use the same relative path that you would if accessing the file from your html/jsp/etc files (i.e. the path is NOT relative to where you place the getScript method, but instead relative to your domain path). For example, for an app at localhost:8080/myDomain:
$(document).ready(function() {
$.getScript('/myDomain/myScriptsDir/constants.js');
...
then, if you have this in a file called constants.js:
var jsEnum = { //not really an enum, just an object that serves a similar purpose
FOO : "foofoo",
BAR : "barbar",
}
You can now print out 'foofoo' with
jsEnum.FOO
There's no constants in JavaScript, but to declare a literal all you have to do is:
var myString = "Hello World";
I'm not sure what you mean by store them in a resource file; that's not a JavaScript concept.
Of course, this wasn't an option when the OP submitted the question, but ECMAScript 6 now also allows for constants by way of the "const" keyword:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
You can see ECMAScript 6 adoption here.
Standard freeze function of built-in Object can be used to freeze an object containing constants.
var obj = {
constant_1 : 'value_1'
};
Object.freeze(obj);
obj.constant_1 = 'value_2'; //Silently does nothing
obj.constant_2 = 'value_3'; //Silently does nothing
In strict mode, setting values on immutable object throws TypeError. For more details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
Well, you can do it like so:
(function() {
var localByaka;
Object.defineProperty(window, 'Byaka', {
get: function() {
return localByaka;
},
set: function(val) {
localByaka = window.Byaka || val;
}
});
}());
window.Byaka = "foo"; //set constant
window.Byaka = "bar"; // try resetting it for shits and giggles
window.Byaka; // will allways return foo!
If you do this as above in global scope this will be a true constant, because you cannot overwrite the window object.
I've created a library to create constants and immutable objects in javascript. Its still version 0.2 but it does the trick nicely. http://beckafly.github.io/insulatejs
Starting ECMAScript 2015 (a.k.a ES6), you can use const
const constantString = 'Hello';
But not all browsers/servers support this yet. In order to support this, use a polyfill library like Babel.
So many ways to skin this cat. You can do this in a closure. This code will give you a read-only , namespaced way to have constants. Just declare them in the Public area.
//Namespaced Constants
var MyAppName;
//MyAppName Namespace
(function (MyAppName) {
//MyAppName.Constants Namespace
(function (Constants) {
//Private
function createConstant(name, val) {
Object.defineProperty(MyAppName.Constants, name, {
value: val,
writable: false
});
}
//Public
Constants.FOO = createConstant("FOO", 1);
Constants.FOO2 = createConstant("FOO2", 1);
MyAppName.Constants = Constants;
})(MyAppName.Constants || (MyAppName.Constants = {}));
})(MyAppName || (MyAppName = {}));
Usage:
console.log(MyAppName.Constants.FOO); //prints 1
MyAppName.Constants.FOO = 2;
console.log(MyAppName.Constants.FOO); //does not change - still prints 1
You can use freeze method of Object to create a constant. For example:
var configObj ={timeOut :36000};
Object.freeze(configObj);
In this way you can not alter the configObj.
Use global namespace or global object like Constants.
var Constants = {};
And using defineObject write function which will add all properties to that object and assign value to it.
function createConstant (prop, value) {
Object.defineProperty(Constants , prop, {
value: value,
writable: false
});
};
Just declare variable outside of scope of any js function. Such variables will be global.