Javascript reserved word and object
Asked Answered
S

4

1

I'm making a dictionary of words, so there are 1,000,000+ words. The problem comes when I need to store the word constructor. I know this is a reserved word in javascript, but I need to add it to the dictionary.

var dictionary = {} 
console.log(dictionary ['word_1']) 
//undefined, this is good
console.log(dictionary ['word_2']) 
//undefined, this is good
console.log(dictionary ['constructor']) 
//[Function: Object] 
// this cause initialization code to break

How can I fix this? I could muck with the it like key=key+"_" but that seems bad. Is there anything else I can do?

Stephan answered 30/10, 2017 at 2:17 Comment(5)
Storing those words as object properties seems like not very good idea to me. Maybe what you can consider is an array of those words: ['word_1', 'word_2', ...] or if you're gonna need some more information along with every word: [{word: 'word_1', anotherProperty: '...'}, ...].Kearse
You will always have to use hasOwnProperty to check reliable if the property was set on the given object.Strawberry
The problem isn't that constructor is a reserved word, it is that objects inherit a constructor property. (In a more general sense there is no problem creating object property names that are reserved words.)Bonded
@Bonded thank you, yes you understand the problem. Can I do something to fix it?Stephan
If you want to test if the property exists directly on the object use .hasOwnProperty(), as already mentioned by t.niesse.Bonded
S
4

Instead of using a JS object, you could use the built-in Map type which uses strings/symbols as keys and does not conflict with any existing properties.

Replace var dictionary = {} with var dictionary = new Map()

Snitch answered 30/10, 2017 at 2:44 Comment(1)
Agree, Map is a better option for you to use. Try: new Map().set('constructor', 'bbb').get('constructor') See Mozilla dev linkTrahern
R
0

Override the constructor key as undefined

According to the MDN Object.prototype page, the only thing that isn't hidden by the __fieldname__ schema is the "constructor field". Thus, you could just initialize your objects via { 'constructor': undefined }.

However, you would have to make sure that in your for .. in statements would filter out all keys with undefined as their value, as it would pick up constructor as a "valid" key (even though it wouldn't before you specifically set it to undefined). I.E.

for(var key in obj) if(obj[key] !== undefined) { /* do things */ }

Check for types when getting/setting

Otherwise, you could just check the type when you 'fetch' or 'store' it. I.E.

function get(obj, key) {
  if(typeof obj[key] !== 'function') // optionally, `&& typeof obj[key] !== 'object')`
    return obj[key];
  else
    return undefined;
}
Repetition answered 30/10, 2017 at 2:30 Comment(0)
C
0

I think you should store all words and translation of them in an array. When you need to translate a word, you can use find method of Array.

For example:

var dict = [
    { word: "abc", translated: "xyz" },
    ...
];

Then:

var searching_word = "abc";
var translation = dict.find(function (item) {
    return item.word == searching_word;
});
console.log(translation.translated);
// --> xyz
Chanellechaney answered 30/10, 2017 at 2:33 Comment(4)
Where did the OP mention translation?Bonded
also, this will likely be way too slow with 200k wordsSnitch
Cause each JS data type has some native methods, so you can't overwrite all of them. Or you can start each word with "@" when you store it in an object, to distinguish with other native method names.Filomenafiloplume
@QuyetTran using a prefix is just a hack and can fail in future. Js e.g. uses @@ to prefix special keys like iteratable.Strawberry
A
0

To achieve expected result , use below option of using index to get value of any key value

var dictionary = {};

var dictionary1 = {
  constructor: "test"
};

//simple function to get key value using index
function getVal(obj, val) {
  var keys = Object.keys(obj);
  var index = keys.indexOf(val);//get index of key, in our case -contructor
  return obj[keys[index]]; // return value using indec of that key
}

console.log(getVal(dictionary, "constructor"));//undefined as expected
console.log(getVal(dictionary1, "constructor"));//test

console.log(dictionary["word_1"]);
//undefined, this is good
console.log(dictionary["word_2"]);
//undefined, this is good

codepen - https://codepen.io/nagasai/pen/LOEGxM

For testing , I gave one object with key-constructor and other object without constructor.

Basically I am getting the index of key first and getting value using index

Aright answered 30/10, 2017 at 2:57 Comment(2)
Wouldn't .hasOwnProperty() be the more obvious way of testing whether an object has a particular own property? Doing an array .indexOf() to look up an object property seems very inefficient. Also, if there is no property matching val, your getVal() function will try to return the value from a property with the key name "undefined", which probably will actually exist in the OP's object given they're creating a dictionary with a million words. (Also, why call Object.keys(obj) twice rather than putting the result in a variable?)Bonded
thanks @nnnnnn, i have updated my answer, I just provided my option as a workaround and as you said hasOwnProperty() works too but someone has already mentioned , so I just gave this answer as an option.and with hasOwnProperty OP can find whether obj has key or not and he will end with same issue while using constructor keyword to get valueAright

© 2022 - 2024 — McMap. All rights reserved.