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?
Related
Im trying to use a command for a chat program and i want to edit a variable with a command like !editvar variablehere value
so if it variablehere = '123' i want to turn '123' into just 123 or something like 'hello' into hello, in simple words im trying to make a string from a chat message into a variable name
ive tried parsing and string.raw and none worked
if(message.startsWith('keyeditvar')) {
console.log(message)
var bananasplit = message.split(' ');
var bananasplitted = json.parse(bananasplit)
console.log(bananasplitted[0].keyeditvar)
var variable = bananasplit[1]
console.log(variable)
var value = bananasplit[2]
console.log(value)
var variable2 = String.raw(variable)
console.log(variable2)
var value2 = String.raw(value)
console.log(value2)
}
i expected it to work ig
im trying to turn a string into a variable name
In Javascript, you don't usually dynamically define new variables with custom names in the current scope. While you can do it at the global scope, you cannot easily do it in the function or block scope without using tools that are generally not recommended (like eval()).
Instead, you use an object and you create properties on that object. You can use either a regular object and regular properties or you can use a Map object with some additional features.
For a regular object, you can do thing like this:
// define base object
let base = {};
// define two variables that contain variable name and value
let someName = "greeting";
let someValue = "hello";
// store those as a property on our base object
base[someName] = someValue;
console.log(base); // {greeting: "hello"}
Then, you can change the value:
someValue = "goodbye";
base[someName] = someValue;
console.log(base); // {greeting: "goodbye"}
Or, you can add another one:
let someOtherName = "salutation";
let someOtherValue = "Dear Mr. Green";
base[someOtherName] = someOtherValue;
console.log(base); // {greeting: "goodbye", salutation: "Dear Mr. Green"}
console.log(base.greeting) // "goodbye"
console.log(base[someName]); // "goodbye"
console.log(base.salutation) // "Dear Mr. Green"
console.log(Object.keys(base)) // ["greeting", "salutation"]
You can think of the Javascript object as a set of key/value pairs. The "key" is the property name and the value is the value. You can get an array of the keys with:
Object.keys(obj)
You set a key/value pair with:
obj[key] = value;
You get the value for a key with:
console.log(obj[key]);
You remove a key/value pair with:
delete obj[key]
With a plain Javascript object like this, the keys must all be strings (or easily converted to a string).
If you have non-string keys, you can use a Map object as it will take any object or primitive value as a key, but it uses get() and set() methods to set and get key/values rather than the assignment scheme of a plain object.
Please, next time put a clean code...
To convert a string to a number. You can use the function : Number(object)
So for example :
Number('123')
will return 123.
If the object value is not a correct number, it will return NaN.
So for example :
Number('hello')
will return NaN.
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");
I know its sounds silly but I am just asking, is there any way of keeping the value of b variable after we delete a variable?
var a = 'some string or number';
var b = a;
delete a;
but b is still = 'some string or number';
or any other way to keep the b value?
delete does not delete values or variables, but deletes properties on an object (MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete).
For instance:
var myObj = { a: 1, b: 2 };
delete myObj.a;
// myObj === { b: 2 }
Of course you can just keep a reference to the value in another variable: var copy = myObj.a (before you delete the property). The variable will then hold the value (for primitives like basic numbers, strings, booleans) or reference (for objects etc.). Either way, your copy will hold the value still after the original property has been deleted:
var obj = { a: "hello" };
var copy = obj.a;
delete obj.a;
console.log(copy); // "hello"
Delete only deletes the property of an object not a variable,
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
delete person.age;
So the variable "b" in the code you have mentioned will retain the value of "a".
If you want to delete a in you case, you have to define a by:
window.a = 'some string or number';
Then delete it by:
delete window.a;
or just
delete a;
delete in javascript just deletes the property, doesn't delete the value that property points to. The value might be gone because there is no more reference point to it.
And in your case, the value of a is a string, so, after to assign a to b, b has its own value "copied" from a. When you delete a successfully, the value of a is also lost, but the value of b is still intact.
I've been trying to get a hold of ES2015 map concept and one thing I don't understand is the following:
var mapRawObj = new Map();
var rawObj = {j:"I like penguin"};
mapRawObj.set(rawObj,true);
console.log(mapRawObj.get(rawObj)); //this outputs true
mapRawObj.set({j:"I like polar bear"},true);
console.log(mapRawObj.get({j:"I like polar bear"})); //this outputs undefined
The first one works, the second one doesn't, and I don't understand why?
I thought when you register object as key, it's the object itself, not the object's name. That's why in the below example when you re-assign the key object, it fails as key?
var obj = { a:"hello ", b:"world "};
var mapObj = new Map();
mapObj.set(obj,true);
obj = {d:34}; //obj is re-assigned
console.log(mapObj.get(obj)); // outputs undefined
Objects with the same data are not equal in Javascript, ie
{ hello: 'world'} === { hello: 'world'} // false
The first example uses the same object as the key for set and get, so the key is identical:
var obj = { hello: 'world'};
obj === obj // true
But the second example creates a new object for the get(), which is not identical to the key used to set the value in the map. Since it's not identical, the map doesn't have anything set against this new key and returns undefined.
Even though the new key has exactly the same data as the original key, the objects aren't referring to the same data internally.
More on object equality
I have an object in a variable var o={};
I want to do something like what .push() method doing in array for my object.
JS code:
// Array:
var ar=[];
ar.push('omid');
ar.push('F');
var got=ar[1];
// above code is standard but not what I'm looking for !
/*-------------------------------------*/
// Object:
var obj={};
/* obj.push('key','value'); // I want do something like this
var got2=obj.getVal('key'); // And this
*/
Is this possible at all ?
var obj = {}
// use this if you are hardcoding the key names
obj.key = 'value'
obj.key // => 'value'
// use this if you have strings with the key names in them
obj['key2'] = 'value'
obj['key2'] // => 'value'
// also use the second method if you have keys with odd names
obj.! = 'value' // => SyntaxError
obj['!'] = 'value' // => OK
Since Object-Literals use a Key->Value model, there is no JS method to "push" a value.
You can either use Dot Notation:
var Obj = {};
Obj.foo = "bar";
console.log(Obj);
Or Bracket Notation:
var Obj = {},
foo = "foo";
Obj[foo] = "bar";
Obj["bar"] = "foo";
console.log(Obj);
Consider reading https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects, as arming yourself with this knowledge will be invaluable in the future.
Here is some javascript magic that makes it work.
Take a look.
var obj = {};
Object.defineProperty(obj,'push',{
value:function(x,y){
this[x]=y;
}
});
obj.push('name','whattttt'); <<<this works!!!
obj;
//{name:'whattttt'}
obj.name or obj['name']..
//whattttt
The reason i defined .push function using Object.defineProperty because i didn't want it to show up as a property of object. So if you have 3 items in object this would have always been the 4th one. And mess up the loops always. However, using this method. You can make properties hidden but accessible.
Though i don't know why you would use this method when there is already a easy way to do it.
to assign a value do this
obj.variable = 'value';
if value key is number or weird do this...
obj[1] = 'yes';
to access number or weird name you also do that
obj[1];
and finally to assign random keys or key that has been generated in code, not hard coded, than use this form too.
var person= 'him';
obj[him]='hello';