I got this code in a function.
The first line works.
this.learningPlan.learnerType = ['abc']; // this line works
but these lines below won't.
properyName = 'learningPlan.learnerType';
this[properyName] = ['abc'];
Is there a way to refer to the this so I can pass the properyName value to the function?
I need this functionality so I can keep the function generic and not mention the specific phrase 'learningPlan.learnerType'. Cause then I can do the following:
function blah(propertyName){
this[properyName] = ['abc'];
}
How does this look:
Edit: Added explanatory comments.
function T() {
this.learningPlan = { learnerType : "aaa" };
this.setVal = function(p, v) {
// Split the property string into its "parts"
// thus "learningPlan.learnerType" becomes ["learningPlan","learnerType"]
var ps = p.split(".");
// Remove and capture the "last" (right-most) property
// From ["learningPlan","learnerType"] this would be "learnerType"
// leaving the array with ["learningPlan"]
var lastProp = ps.pop();
// Work "down" the object finding each level object finally returning
// the property object containing the property you wish to set
var o = ps.reduce(function(a,e) {
// This checks that each object["property"] exists and if
// it doesn't then it creates an empty object so that it can
// continue traversing down the property hierarchy.
// Given the property string "learningPlan.learnerType" if the
// property this.learningPlan didn't exist then attempting to
// reference this.learningPlan.learnerType would throw an error
// since learnerType is not a property of undefined. This is, I
// believe, the error you are experiencing. Using (a[e] || {})
// ensures that a[e] references something so that traversal
// can continue.
a[e] = (a[e] || {});
// This simply returns the property so that the reduce can keep
// moving through the array
return a[e];
}, this);
// Finally, we set the value for the last property in our string.
// The above reduce would walk down 'this' finding/setting each
// property until it reached the last string we left in our array
// after the pop and thereby returning a reference to that property
// into our variable "o". We then use the last property string as a
// property of "o" to set our value.
o[lastProp] = v;
};
}
It will allow you to do things like:
var t = new T();
t.setVal("learningPlan.learnerType", "def");
Related
I don't understand the purpose of this = sign on the sixth line in the code block below. I understand how the argument grabs each index number of the array, I just don't understand why chineseFood[array[0]] = array[array.length-1]; In other words, I don't get the purpose of the equal sign as if it were almost comparing each other to be stored in the empty object that is stored in the variable chineseFood. Could someone please clarify? It would be much appreciated.
function transformFirstAndLast(array) {
var chineseFood = {};
//takes 1st element (at index 0) and sets it to the last element (nth index): array(length-1)
chineseFood[array[0]] = array[array.length - 1];
return chineseFood;
}
console.log( transformFirstAndLast(['Orange', 'Lemon', 'Pork', 'Chicken']) );
Output Below
{Orange: "Chicken"}
The equals sign is not comparison, it is assignment. chineseFood is an object, which means that it can be treated like a dictionary, and its properties can be accessed using the [] operator instead of the . operator:
myObj = {
foo: "bar"
};
console.log(myObj["foo"]); // bar
console.log(myObj.foo); // bar
Likewise, you can also assign properties this way:
myObj = {};
myObj["foo"] = 3;
console.log(myObj["foo"]); // 3
console.log(myObj.foo); // 3
This is what your code is doing. It is retrieving the value of array[array.length-1], which is "Chicken". Then it is assigning this value to the property of chineseFood that has the name represented by array[0], which happens to be "Orange". Thus, the property named Orange on chineseFood is set to array[array.length - 1], which is why chineseFood evaluates to {Orange: "Chicken"}.
This method of accessing properties is especially useful when you don't know the name of the property you will be changing in advance, as is the case with this code, or when you want to create properties that have names that would otherwise be illegal:
myObj = {
".you can't usually use with spaces or start w/ periods": false
};
myObj[".you can't usually use with spaces or start w/ periods"] = true;
console.log(myObj[".you can't usually use with spaces or start w/ periods"]);
// there is no way to read this property the normal way
Basically what is does is:
your object is :
var obj = {Orange: "Chicken"};
And Your array is :
var arr = ['Orange','Lemon','Pork','Chicken']
What this line says is pick first element of the array and check for this prop in object and change its value to last element of array, here:
arr[0] = "orange";
So this line :
obj[arr[0]] can be seen as obj['orange'].
After that you change its value:
Obj[arr[0]] = arr[arr.length-1] which can be written as obj['orange'] = 'chicken'
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?
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()
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;
}
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
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
I have a tes test service with two objects shown here in my Typescript code:
test: ITestView;
tests: ITestView[];
This code checks each object in the tes.tests array and when an id matches it assigns an object in the array to equal another object tes.test:
tes.tests.forEach((test: ITestRow) => {
test.current = false;
if (test.id == id) {
tes.test = test; // << Linking them somehow here
test.current = true;
}
});
Later on I do this:
tes.test.current = false;
This code sets the value of tes.tests[0].current to false and tes.test.current to false.
When I now do this:
tes.test = null;
This code sets the value of tes.test to null but does not do anything to the tes.tests[] array.
Can someone explain why it does not effect the tes.tests[] array?
test = foo; // test references existing object foo
tests[0] = test; // test[0] also references existing object foo
test = null; // test doesn't reference anything, but tests[0] still does
Depending on what you expect, you could do:
tests[0] = null; // tests[0] doesn't reference anything
or:
tests.splice(0,1); // removed the 1st item from the tests
// not tests array became shorter!
I think the quick and simple answer is that
tes.test = null;
doesn't destroy the object it's pointing to. tes.test now points to nothing.
To clarify, tes.test.current = falsechanged both objects was because it referenced the current key of the object tes.test was pointing to.
tes.test = null;
The above code doesn't make any changes to tes.tests[] because it simple makes tes.test point to nothing instead of changing the object it is pointing to.
I hope I was clear!
I feel like this will be one of those "oh jeez, how did I even ask this question" questions, but...
// So I create an object:
var o = {};
// I assign a string value to a variable:
var prop1 = "prop_key";
// And I use that variable that resolves to that string as the property name:
o[prop1] = "value1";
// => So far so good, the property key is the right value:
console.log(o); // => Object {prop_key: "value1"}
// Moving on, I am malicious and overwrite the `prop1` variable, replacing the original value to say, another string:
prop1 = "evil_string";
// And just to make sure it worked:
console.log(prop1); // => evil_value:
// AND YET, when I query the object...
console.log(o); // => Object {prop_key: "value1"}
Shouldn't it now output Object{"evil_value": "val1"} since o[prop1] no longer points to that original prop_key value?
So, I want to create an object (semi-automatically) using Jquery.
Instead of posting all of my code here, I'll give an example of what I want to do:
var myobject = {
'name1': {
'coord1':true,
'coord2':false,
'coord3':false,
},
'name2': {
'coord4':true,
'coord5':false,
'coord6':false,
}
}
1) I first want to check if 'nameX' is already in my object, if so, continue to step 2, if not, I want to add the name, and coordX with value true or false.
2) If 'nameX' is in the array, I want to check i 'coordX' is in the array. If so, I need to check if the corresponding value (true or false) is the same, and if not, replace it. If 'CoordX' is not in the object, I want to add it with the corresponding value.
For example:
var mynewname = 'name3';
var mynewcoord = 'coord5';
var mynewvalue = 'true';
var mynewname2 = 'name1';
var mynewcoord2 = 'coord4';
var mynewvalue = 'false';
When checking these values with the object this should give:
var myobject = {
'name1': {'
coord1':true,
'coord2':false,
'coord3':false,
'coord4':false
},
'name2': {
'coord4':true,
'coord5':false,
'coord6':false
},
'name3':{
'coord5':true
}
}
I hope someone can help me with this. Thank you
In order to find out if an object contains a property with a given name, you have a couple of choices.
You can use the in operator with a string property name:
if ("nameX" in myobject) {
// The object referenced by `myobject` (or its prototype)
// has its own property called "nameX"
}
else {
// It doesn't
}
in will check the object and its prototype. That probably doesn't matter for the simple objects you're using.
Or you can use hasOwnProperty, which only checks the object and not its prototype:
if (myobject.hasOwnProperty("nameX")) {
// The object referenced by `myobject` has its own property called "nameX"
}
else {
// It doesn't
}
So for instance, if you want to see if name1 is in myobject and, if not, add name1 referencing a blank object, you'd do this:
if (!("name1" in myobject)) {
myobject.name1 = {}; // No, add it and give it a blank object as its value
}
And similarly for the coordX properties of the objects you're referencing from myobject.nameX.