JS object behavior is different when I change the property value - javascript

I'm completely new to JS and trying to learn on my own. Using below code -
var me = {
name: {first:"justin"}
},
name = me.name;
name = {first: "alexis"};
Why would document.write(me.name.first + "</br>"); return justin?
and
why would document.write(this.name.first); doesn't return anything?
Please can you explain me?
Thanks,
Me

Just change the variable name name to other string, for example: n. Everything will work perfect.
var me = {
name: {first:"justin"}
},
n = me.name;
n = {first: "alexis"};
The reason is this.name.first will refer to window.name.first. But window.name has special usage in javascript and has to be a string.

Related

Use variable to store "change.doc" path

I'm trying to use variable as a firestore doc path :
console.log(change.doc.data().m_1.name); <----- This work well !
a = 1;
let me = change.doc.data().m_+a; <----- But not that....
console.log(me.name);
How can i do that ?
Thank you in advance ! :)
You should use brackets when using dynamic property.
let me = change.doc.data()['m_' + a];
I think you want to build the name of the key as its own variable and use that to index into the object.
const a = 1;
const key = "m_" + a;
const me = change.doc.data()[key];
When you use your a variable in your example you're asking JS to add the number 1 to your functions output. This is not the correct way. You want to use a key to access the data from your data() functions return output as shown below.
change = {
doc: {
data: function() {
return {
m_1: {
name: "Mario",
occupation: "plumber",
siblings: 1,
age: 24
},
m_2: {
name: "Mike",
occupation: "developer",
siblings: 3,
age: "28"
}
}
}
}
}
console.log("Old way:" + change.doc.data().m_1.name);
const a = 1;
let me = change.doc.data()['m_' + a];
console.log("Desired way: " + me.name)
I have assumed a simple data structure derived from your question but I am not certain that it's what you get. But it might look a little like it.
EDIT awww.... The page didn't refresh and I did not see the two first answers :( well... at least we agree

How to convert arrays to objects in javascript?

How could I rewrite this code to object javascript. Since Array usage is prohibed, I can only use objects here. Insted of pushing values to array, I would like to push this values into objects.
var container = [];
document.addEventListener("submit", function(e){
e.preventDefault();
});
window.addEventListener("load",function(){
var submit = document.getElementsByClassName("btn-primary");
submit[0].addEventListener("click",add,false);
document.getElementById("pobrisi").addEventListener("click",deleteAll,false);
var dateElement = document.getElementById('datum');
dateElement.valueAsDate = new Date();
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1;
var yyyy = today.getFullYear();
if(dd<10){
dd='0'+dd
}
if(mm<10){
mm='0'+mm
}
today = yyyy+'-'+mm+'-'+dd;
dateElement.setAttribute("min",today);
});
function add() {
var title = document.getElementById("title").value;
var type = document.getElementById("type").value;
var datum = document.getElementById("datum").value.split("-");
datum = datum[2]+". "+datum[1]+". "+datum[0];
var data = new Book(title,type,datum);
container.push(data.add());
display();
}
function display(data) {
var destination = document.getElementById("list");
var html = "";
for(var i =0;i <container.length; i++) {
html +="<li>"+container[i]+"</li>";
}
destination.innerHTML = html;
}
function deleteAll(){
container=[];
document.getElementById("list").innerHTML="";
}
Wondering if is possible to write this code whitout any array usage.
initial remarks
The problem here, in my estimation, is that you haven't learned the fundamentals of data abstraction yet. If you don't know how to implement an array, you probably shouldn't be depending on one quite yet. Objects and Arrays are so widespread because they're so commonly useful. However, if you don't know what a specific data type is affording you (ie, what convenience does it provide?), then it's probable you will be misusing the type
If you take the code here but techniques like this weren't covered in your class, it will be obvious that you received help from an outside source. Assuming the teacher has a curriculum organized in a sane fashion, you should be able to solve problems based on the material you've already covered.
Based on your code, it's evident you really have tried much, but why do you think that people here will come up with an answer that your teacher will accept? How are we supposed to know what you can use?
a fun exercise nonetheless
OK, so (we think) we need an Array, but let's pretend Arrays don't exist. If we could get this code working below, we might not exactly have an Array, but we'd have something that works like an array.
Most importantly, if we could get this code working below, we'd know what it takes to make a data type that can hold a dynamic number of values. Only then can we begin to truly appreciate what Array is doing for us.
// make a list
let l = list(1) // (1)
// push an item on the end
l = push(l, 2) // (1 2)
// push another item on the end
l = push(l, 3) // (1 2 3)
// display each item of the list
listeach(l, function (x) {
console.log(x)
})
// should output
// 1
// 2
// 3
runnable demo
All we have to do is make that bit of code (above) work without using any arrays. I'll restrict myself even further and only use functions, if/else, and equality test ===. I see these things in your code, so I'm assuming it's OK for me to use them too.
But am I supposed to believe your teacher would let you write code like this? It works, of course, but I don't think it brings you any closer to your answer
var empty = function () {}
function isEmpty (x) {
return x === empty
}
function pair (x,y) {
return function (p) {
return p(x,y)
}
}
function head (p) {
return p(function (x,y) {
return x
})
}
function tail (p) {
return p(function (x,y) {
return y
})
}
function push (l, x) {
if (isEmpty(l))
return list(x)
else
return pair(head(l), push(tail(l), x))
}
function list (x) {
return pair(x, empty)
}
function listeach (l, f) {
if (isEmpty(l))
return null
else
(f(head(l)), listeach(tail(l), f))
}
// make a list
let l = list(1) // (1)
// push an item on the end
l = push(l, 2) // (1 2)
// push another item on the end
l = push(l, 3) // (1 2 3)
// display each item of the list
listeach(l, function (x) {
console.log(x)
})
closing remarks
It appears as tho you can use an Object in lieu of an Array. The accepted answer (at this time) shows a very narrow understanding of how an object could be used to solve your problem. After this contrived demonstration, are you confident that you are using Objects properly and effectively?
Do you know how to implement an object? Could you fulfill this contract (below)? What I mean by that, is could you write the functions object, set, and get such that the following expressions evaluated to their expected result?
In case it's not obvious, you're not allowed to use Object to make it happen. The whole point of the exercise is to make a new data type that you don't already have access to
m = object() // m
set(m, key, x) // m
get(m, key) // x
set(m, key2, y) // m
get(m, key2) // y
set(m, key3, set(object(), key4, z)) // m
get(get(m, key3), key4) // z
I'll leave this as an exercise for you and I strongly encourage you to do it. I think you will learn a lot in the process and develop a deep understanding and appreciation for what higher-level data types like Array or Object give to you
Since this is a homework I feel like I shouldn't solve it for you, but rather help you in the right direction.
Like Slasher mentioned you can use objects
With JavaScript object one book would look something like
const book = {
title: 'my awesome title',
type: 'novel'
};
book is the object
title is a property with a value 'my awesome title'
type is a property with a value 'novel'
But objects can also have other objects as values. Something like
const BookShelf= {
Book1: {
Title: 'my awesome title',
Type: 'novel'
},
Book2: {
Title: 'my horrible title',
Type: 'sci-fi'
}
};
You can reference the books in the bookshelf in two ways
const book1 = BookShelf.Book1 // Returns the book1 object
const title1 = Book1.Title; // Get the title
const sametitle = BookShelf.Book1.Title // Returns title for book1, same as above.
You can also use brackets:
const book1 = BookShelf['Book1'];
const title1 = BookShelf['Book1']['Title];
You can even make new properties on a object like this:
const Book3 = {
Title: 'running out of ideas'
Type: 'memoir'
};
BookShelf['Book3'] = Book3;
Now the BookShelf has a Book3 property. So your BookShelf object looks like
const BookShelf= {
Book1: {
Title: 'my awesome title',
Type: 'novel'
},
Book2: {
Title: 'my horrible title',
Type: 'sci-fi'
},
Book3 = {
Title: 'running out of ideas'
Type: 'memoir'
};
};
That should get you started :)
JavaScript Objects is a good way to go
1- define a new object:
var myVar = {};
or
var myVar = new Object();
2- usage
// insert a new value, it doesn't matter if the value is a string or int or even another object
// set a new value
myVar.myFirstValue="this is my first value";
// get existing value and do what ever you want with it
var value = myVar.myFirstValue

How can I use underscore in name of dynamic object variable

Website that I'm making is in two different languages each data is saved in mongodb with prefix _nl or _en
With a url I need to be able to set up language like that:
http://localhost/en/This-Is-English-Head/This-Is-English-Sub
My code look like that:
var headPage = req.params.headPage;
var subPage = req.params.subPage;
var slug = 'name';
var slugSub = 'subPages.slug_en';
var myObject = {};
myObject[slugSub] = subPage;
myObject[slug] = headPage;
console.log(myObject);
Site.find(myObject,
function (err, pages) {
var Pages = {};
pages.forEach(function (page) {
Pages[page._id] = page;
});
console.log(Pages);
});
After console.log it I get following:
{ 'subPages.slug_en': 'This-Is-English-Sub',
name: 'This-Is-English-Head' }
Is you can see objectname subPages.slug_en is seen as a String insteed of object name..
I know that javascript does not support underscores(I guess?) but I'm still looking for a fix, otherwise i'll be forced to change all underscores in my db to different character...
Edit:
The final result of console.log need to be:
{ subPages.slug_en: 'This-Is-English-Sub',
name: 'This-Is-English-Head' }
Insteed of :
{ 'subPages.slug_en': 'This-Is-English-Sub',
name: 'This-Is-English-Head' }
Otherwise it does not work
The reason you are seeing 'subPages.slug_en' (with string quotes) is because of the . in the object key, not the underscore.
Underscores are definitely supported in object keys without quoting.
Using subPages.slug_en (without string quotes) would require you to have an object as follows:
{ subPages: {slug_en: 'This-Is-English-Sub'},
name: 'This-Is-English-Head' }
Which you could set with the following:
myObject['subPages']['slug_en'] = subPage;
Or simply:
myObject.subPages.slug_en = subPage;

combining text into a variable name in javascript

i have looked for an answer to this, but im also not sure im using the correct wording to give me a good search result. So without further adoo.
I am trying to make a random name generator in JavaScript, and I don't want a 300 line switch if it can be avoided. No Jquery if it can be avoided, mainly as i want to learn how to code in JS, for no other reason than that. But if i have to use Jquery, so be it. Learning and all.
The idea is that the script will take the race, gender, then randomly select the first name, surname and proffesion from an array. I can get this to work in IF statements and switches. But I want to try it on as little code as possible. The example below is for humans, but the idea is to pretty much use any fantasy race... dwarves, elves... yes its for dungeons and dragons. Maybe later on use JSON for the array data, but that's later.
var HumanFemale = ["Diane","Laura","Amy"];
var HumanMale = ["Steve","Dave","Tony"];
var HumanS = ["Druss","Hale","Taylor"];
var Proff = ["Theif","Mercenary","Soldier"];
function chargen(race,gender){
var x = race.concat(gender);
var xs= race.concat('S');
document.getElementById("OutputR").innerHTML= race;
document.getElementById("OutputG").innerHTML= gender;
document.getElementById("OutputF").innerHTML= x[Math.floor(Math.random()*x.length)];
document.getElementById("OutputS").innerHTML=xs[Math.floor(Math.random()*xs.length)];
document.getElementById("OutputJ").innerHTML=Proff[Math.floor(Math.random()*Proff.length)];
}
Maybe I need dynamic variables, but i'm not sure how to convert text into a var name.
Thanks
I think an object probably makes your life a little easier, but the idea is generally the same as what you appear to have.
In JavaScript you can reference a property of an object like an array. This means that if you have a property name that can be variable, you can use the array convention to fetch the property instead of the "." convention.
Here's an example:
var example = {
"first": "hello",
"second": "world"
}
//Using dot-notation
alert(example.first); //alerts "hello"
alert(example.second) //alerts "world"
//Using array-notation
alert(example["first"]); //alerts "hello"
alert(example["second"]); //alerts "world"
Now, if the property we want is variable, we can't use the dot-notation, but we can use the array-notation:
var prop_name = "second";
//Using dot-notation
alert(example.prop_name); //throws an error (undefined property)
//Using array-notation
alert(example[prop_name]); //alerts "world"
So, if you create essentially a dictionary object, you may find it's easier/more concise to complete your task:
var dict = {
"Human": {
"Male": ["Steve", "Dave", "Tony"],
"Female": ["Diane", "Laura", "Amy"],
"Surname": ["Druss", "Hale", "Taylor"]
},
"Elf": {
"Male": [/* names */],
"Female": [/* names */],
"Surname": [/*names */]
}
}
function rand_attributes(race, gender) {
var first_name_index = Math.floor(Math.random() * dict[race][gender].length),
last_name_index = Math.floor(Math.random() * dict[race]["Surname"].length),
first_name = dict[race][gender][first_name_index],
last_name = dict[race]["Surname"][last_name_index];
//Now first_name and last_name each contain random values
//Do what you need to with those values from here
}
That code is untested, but it should at least conceptually work out.
Here's what I crudely chucked together.
var Proff=["Theif","Mercenary","Soldier"];
var CharacterName={};
CharacterName['human']={};
CharacterName['human']['female'] = new Array('Diane','Laura','Amy');
CharacterName['human']['male'] = new Array('Steve','Dave','Tony');
CharacterName['human']['surname'] = new Array('Druss','Hale','Taylor');
//just add more stuff here!
document.getElementById('OutputR').innerHTML= 'boo';
function chargen(race,gender){
document.getElementById('OutputR').innerHTML= race;
document.getElementById('OutputG').innerHTML= gender;
document.getElementById('OutputF').innerHTML= grabrandom(CharacterName[race][gender]);
document.getElementById('OutputS').innerHTML= grabrandom(CharacterName[race]['surname']);
document.getElementById('OutputJ').innerHTML= grabrandom(Proff);
}
function grabrandom(arrayofvalues){
return arrayofvalues[Math.floor(Math.random()*arrayofvalues.length)];
}
chargen('human','female');
It's nothing special and a couple of bits could be sharpened, but it's functional and gives you the idea on how it could be done.
The solution i got, heavily based on xjstratedgebx's responce.
var names = {
"Human": {
"Female": ["Diane","Laura","Amy"],
"Male": ["Steve","Dave","Tony"],
"Surname": ["Hall","Young","Taylor"]
}
}
function namegen(race,gender){
var firstname = names[race][gender][Math.floor(Math.random() * names[race][gender].length)];
var lastname = names[race]["Surname"][Math.floor(Math.random() * names[race]["Surname"].length)];
document.getElementById("OutputR").innerHTML= "Human";
document.getElementById("OutputG").innerHTML= "Female";
document.getElementById("OutputF").innerHTML= firstname;
document.getElementById("OutputS").innerHTML= lastname;
}

Is there a simpler way to send variable name and content to the console?

I often need to monitor the contents of variables when testing programs like this:
var anObject = {aProperty:true}; // this is just an example.
console.log('anObject.aProperty: ' + anObject.aProperty); <-- typed it twice.
I type the name of the variable into a string followed by typing the same thing again to reference the value.
It seems like an unnecessary duplication to write the same thing twice every time. Is there a way to do this by having to only write the name once using a function?
For example:
function show(value) {
console.log("'" + ??? + "':" + value):
}
so it can be used like this (or something similar):
show(anObject.aProperty);
The above is just a simple example. Basically what I'm asking is whether there is a way to get the name of the variable that was passed into a function so that the name can then be output as part of a string showing the value of the variable.
Haters are gonna hate:
http://jsfiddle.net/coma/6HTnB/
var anObject = {
aProperty: ['uno', 'dos', 'tres']
};
var log = function(object, property) {
var evil = 'object.' + property;
console.log(evil, eval(evil));
};
log(anObject, 'aProperty[2]');
Or even worse:
http://jsfiddle.net/coma/6HTnB/2/
var anObject = {
aProperty: ['uno', 'dos', 'tres']
};
var show = function(a) {
console.log(a + ':', eval(a));
};
show('anObject.aProperty[2]');
Well, eval is not evil per se, but the second approach is kind of ugly since the function needs to be in the correct scope.
Here is how I would write such a show() function:
function show(object, property) {
console.log(property + ":", object[property]);
}
To use it:
var mouse = { x: 100, y: 200 };
show(mouse, 'x');
And if you want to test it: http://jsfiddle.net/IQAndreas/c9SUm/
You don't print out the name of the object (and due to the way JavaScript variables and references work, there is no easy way to do so), you only get the name of the property you want to access. If you want the name of the object as well, you could manually print it out before listing the properties:
var mouse = { x: 100, y: 200 };
console.log("== mouse ==");
show(mouse, 'x');
show(mouse, 'y');
Which outputs:
"== mouse =="
"x:" 100
"y:" 200
You can however print the type of the object, (if you are using JavaScript's class features that is, otherwise, anything created with {} is just said to be an Object):
function show(object, property) {
var className = object.constructor.name;
console.log(className + "#" + property + ":", object[property]);
}
Sample output (assuming you have created the Mouse class):
"Mouse#x:" 100
"Mouse#y:" 200
And if you want to test it: http://jsfiddle.net/IQAndreas/c9SUm/2/
Based on coma's answer, I think this may be the solution:
function show() {
return function (value) {
console.log(value + ':', eval(value));
};
};
function aTest() {
obj = {x:1, y:2}; show()('obj');
};
function bTest() {
obj = {x:3, y:4}; show()('obj');
};
aTest(); // obj: { x: 1, y: 2 }
bTest(); // obj: { x: 3, y: 4 }

Categories

Resources