Is it possible to use ES6 Symbols in LocalStorage - javascript

When using a ES6 Symbol as the key for a key/value pair in LocalStorage, can we then still access it after reloading the page?
I found this tutorial that claims this to be possible when using Symbol.for, but so far I have no success and get an undefined when I try to retrieve the LocalStorage key/value pair.
As a side question: does it make sense to use Symbols over here?

You can use Symbols as keys in an object - that's one of theirs purposes. But localStorage is not your typical object. It has an API to set/get values in the store, which the tutorial you have shared is not using: localStorage.{set,get}Item().
Unfortunately localStorage doesn't accept Symbols as keys, only strings. So the real answer is no, you can't use Symbols as keys in LocalStorage, but...
You could do the following. It isn't actually using a Symbol as the key, but the Symbols toString() representation:
const sym = Symbol.for('Hello').toString()
localStorage.setItem(sym, 'World')
document.write('Hello, ' + localStorage.getItem(sym))
[ Check it out on jsbin.com ]
As a side question: does it make sense to use Symbols over here?
I suppose you could use reserved Symbols (e.g. Symbol.iterator) to extend the functionality of the localStorage global. But that's kind of besides the point.

Related

Javascript array access(with string literal as key) - space complexity

Sample object:
const myArray = {'attributes':{ 'fullName': 'Foo Bar'};
During code review, I found that one key(string type) was being used to access the object in multiple functions.
Now my question is, should we access the object directly by using the string literal as key, e.g. myArray['attributes']['fullName']
or use a constant instead, like :
const ATTRIBUTES = 'attributes';
const FULLNAME = 'fullName';
someVar = myArray[ATTRIBUTES][FULLNAME];
According to my knowledge, the latter approach is better because it reserves only one memory block.
But my friend had a different opinion, he told if we use the string literal for key, then it won't have any impact on memory.
Now, I am confused and don't know which approach is better.
Could anyone help me understanding which one is better with explanation?
Something like this will make no performance difference. In my opinion the second option is less readable too.
I would take
myArray.attributes.fullName
because it shows the compilter to use a constant to a value, instead of using brwacket notation where the structure is aimed for dynamic use.
I don't know about the memory, and I'm using the first option, but in case of the key changing I'll have to modify it at several places rather than one so for code retake it's not so good

Is Object.entries vulnerable to object injection attacks?

Let's say I want to build a table out of the key/values in a hash (not what I was doing, but similar enough). This is some code that would be delivered as part of a web page. The first version I wrote was like so:
let table = '';
Object.keys(foo).forEach(k =>
// eslint-disable-next-line security/detect-object-injection
table += `||${k}|${foo[k]}||\n`
);
This triggered eslint's object injection error (which gives a lot of false positives but this object isn't coming from client input so it seems safe). But I wanted to try and refactor to get rid of the object injection issue:
let table = '';
Object.entries(foo).forEach(kv => table += `||${kv[0]}|${kv[1]}||\n` );
That got rid of the security/detect-object-injection problem according to eslint. But I wanted to make sure and I can't find any discussion of how to work around this on here.
Is Object.entries better for iterating a hash (and values) vs. Object.keys when it comes to object injection?
The two methods are equivalent. The difference is that in the second case, simple static analysis can determine that there's no object injection, since there's no use of a variable in the object index. In the first case, eslint can't tell that k is a safe index, but we can tell it easily because Object.keys() doesn't return user input.
The warning in the first version is a false positive. Object injection only occurs when the key comes from an untrusted source, since it allows them to access any property of the object. But if you're generating the list of properties in your code, it's not injection. The false positives happen because eslint doesn't know where k comes from in foo[k], so it assumes the worst.
Read The Dangers of Square Bracket Notation
If your intent is to process all the properties, then there's no object injection when you get k from Object.keys(). And for the same reason, there's no object injection when you use Object.entries(), since it's getting the same keys and values.

What is the right way to store JavaScript source code in a json object?

I want to edit JavaScript in a textarea and store it back into a JavaScript object. For example I have this object:
var item1 = {
'id' : 1,
'title':'title',
'sourcecode' : "alert('hallo')"
};
If I would change the content to alert("hallo") or a even more complex example does this break my object?
I would think there is some escape function like this https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/escape. But it is marked as deprecated.
So if this is deprecated what would be the right way for storing complex JavaScript code into a JavaScript object?
Should I use stringify ?
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
The JSON.stringify() method converts a JavaScript value to a JSON
string, optionally replacing values if a replacer function is
specified, or optionally including only the specified properties if a
replacer array is specified.
This does not read like there is an automated escape build in.
If you need to send the data to a server, I'd say you should encodeURI your sourceCode, and then JSON.stringify the entire object. When retreiving data from the server, you should decodeURI the sourceCode

Meteor Session.get and Regex

Is there any possibility (in Meteor) to get all Session keys and match them with Regex? like
Session.set( /(?:^|\W)word-(\w+)(?!\w)/g , false )
I want set them all to false. But i know only first word in key name, and it is always the same.
Session is not designed to work with regexp. On the other hand you can easily use client-side collections for storing information of this type. So
var mySession = new Meteor.Collection(null); // null is important!
mySession.update({key: {$regexp: /* regexp */}}, {$set: {value: false}});
Remember that Collection is a reactive data-source just like Session, so this will behave almost identically as Session in terms of templates rendering. The only difference is that the data from mySession will be erased after hot code push. This can be fixed by using reload or amplify package but it is quite a different story.

Efficient Javascript Array Lookup

If I have a whitelist of strings that I want to check everything the user inputs into my javascript program, what's the most efficient way to do that? I could just have an array and loop through it until a match has been found but that's O(N). Is there an yway to do it that's better and doesn't involve any sort of key value lookup, just checking to see if that value exists?
EDIT: I guess what I'm looking for is the equivalent of a set in C++ where I can just check to see if a value I'm given already exists in the set.
Just make it a simple js object instead of an array.
var whitelist = {
"string1":true,
"string2":true
}
and then you can just check if(whitelist[str]) to check if its available.
Or use if(str in whitelist).
I expect that the first will have slightly better performance (I haven't verified that), but the second is more readable and makes the purpose clear. So its your choice of which is a better fit.
Sort the array, use binary search for the look-ups.
Or
Create an object where the key is the item and use the hash look-up whitelist[value] != undefined
I think you'll find that key-value lookup is almost identical in performance to some kind of set implementation without values. (Many standard libraries actually just implement a set using a map)

Categories

Resources