Complex use of function parameter in javascript - javascript

function me(a, b) {
function he(c, d) {
if(!a[c]) {
}
}
}
Please someone explain 'if(!a[c])' for me.
why this square bracket is used here in [c] though it is a parameter. it is not an array obviously.
what does if(!a[c]) make sense? how two parameters are used like this?

There is nothing special about that code.
It is saying, in English, If the property c of a is falsey, then the condition is true.
In JavaScript, bracket notation can be used to access properties of an object or members of an array.
For example, someArray[5] will access the 6th member of the array, while someObject['someProp'] will access someProp of the object someObject.

The argument a is likely an object. The syntax:
if (!a[c])
Checks to see if the property in the variable c on the a object does not have a truthy value. This could be if it was null, false, undefined or any other falsey value.
The bracket notation can be used with property names. So, if you have an object like this:
var x = { name: "John"};
Then, you can access that property like in any of these ways:
x.name
x["name"];
// Or, if the property name is in a variable
var prop = "name";
x[prop]
Your example is using a version of the last of the above three options when the property name is in another Javascript variable.

In javascript, properties can be accessed dynamically using the square-bracket syntax.
Consider the following:
var person = {name:'Sarah'};
console.log(person.name); // logs 'Sarah';
Sometimes, you might want to dynamically access properties of an object, using a variable that holds the name of the property you want to access. The above example could also be written like this:
var person = {name:'Sarah'};
var prop = 'name';
console.log(person[prop]); // logs 'Sarah';

Related

What are JavaScript Objects and Properties?

Can anyone explain objects and properties to me in Javascript in layman's terms? The Javascript MDN documentation is confusing me.
I am trying to solve a problem in a Javascript tutorial about objects and properties The question is below and my attempt at the code, I think I followed the MDN as far as I can grasp it. Any help would be appreciated!
Question: Add the value of the property argument as a key on the object argument.
The value of the new property should be set to null.
Return object after adding the new property.
Input Example:
{}, 'hello'
{ x: 5 }, 'y'
Output Example:
{ hello: null }
{ x: 5, y: null }
note: the property name is NOT 'property'. The name is the value of the argument called property (a string).
My code:
//NOTE: the function addProperty(object, property) was already in the console and I have to write the solution inside of it.
function addProperty(object, property) {
// code here
let result = addProperty({x: 5}, 'y');
obj[property] = null;
return obj;
}
addProperty(x, 'y');
Layman's explanation:
An object is a collection of properties. You can give a name to the object to keep things organized. For example, lets create a person object.
var person = {};
The object has no properties right now. To further describe the person we can add properties to the object.
person.Name = 'Zim';
person.Age = 29;
person.Gender = 'Male';
person.Weight = 80;
Now this object has some properties to help describe it. A different way to write the same thing:
var person = { Name: 'Zim', Age: 29, Gender: 'Male', Weight: 80 };
If we had to create a program that displays a list of people, storing all of our information inside objects would help keep things organized.
Object properties are sometimes referred to as keys.
Adding properties to objects:
You can add a property to an object using brackets, just like you had in your addProperty function. If you just need it to add a property, set that property to null and return the result it would look something like this:
function addProperty(object, property) {
// code here
object[property] = null;
return object;
}
This would let us create a properies on our object from above by calling
addProperty(person, 'Occupation');
addProperty(person, 'Income');
addProperty(person, 'Height');
I think you're over-thinking it.
First the question:
Add the value of the property argument as a key on the object
argument. The value of the new property should be set to null. Return
object after adding the new property.
emphasis added
So, property will be the KEY (of a key/value pair), and the VALUE will be null of object, which we are also passing in as an argument.
One way to interrogate key/value pairs on a javascript object is through the square-brackets []. So, if you have a key/value pair: { foo: "bar" }, you can get "bar" by: object['foo']. You can also create new key/value pairs like this, so your function can look like:
function addProperty(object, property) {
object[property] = null;
return object;
}
var obj = {};
obj = addProperty(obj, "hello");
console.log(obj);
console.log(addProperty({x: 5}, 'y'));
What our function is doing is taking the object passed into it (as an argument), creating a new KEY with our property argument, and setting its VALUE to null, and simply returning the object.
*Side note -
Be careful, the code you have posted will create an endless recursive loop, as you keep calling the same function with no way to break out of it.
This particular example is simple:
var one={};
var two={x:5};
function addProperty(object property){
obj[property]=null;
return obj;
}
addProperty(one, 'hello');
addProperty(two, 'y');
Objects in javascript are really flexible, their properties can be added or removed, even when set from the very beginning.
If you take:
var x={};
x will be an object with nothing in it, but if instead of that you write:
var x={
inner:'b'
};
x will be an object with a property called inner which value is 'b', now, if we want to access that property we could do something like this:
var valueOfInner=x.inner;
or
var valueOfInner=x['inner'];
The same if we want to change the value of that property:
x.inner=8;
or
x['inner']=8;
Now, you'll notice that when we use x.['inner'], we could very well use instead:
var propertyName='inner';
x[propertyName]=8;
So you can access and modify a property of an object without actually knowing exactly which property you're manipulating.
Finally, if you're (willing or by accident) trying to set the value of a property that doesn't exists, the property will be automatically be created, for example:
x['blah']=456;
Will create the property blah even when it wasn't defined at first.
Edit: yes, you can define the object and define its properties later:
var x={};
//more code or something
x['y']=777;//now x has a y property with the value 777
a property is a key:
let obj = {
name: 'Jordan',
age: 15
}
obj.name is a property, same goes for obj.age.

Using a functions argument to find and objects key value pair?

I'm trying to find a key value pair value but i want to pass the key in as an argument but it isn't seeming to work.
function drawPieChart(){
var findData = function(variable){
return dailyLog.find({createdBy: Meteor.user().username}, {fields: {variable: 1}}).fetch()[0].variable;
};
var data = [
{
value: findData(adherence),
color: "#CBDDE7"
}...
I want variable to be passed in twice, once to sort and other to find the value but it is actually looking for the key value pair "variable" which obviously doesn't exist.
How do i make it be seen as the argument?
There are two aspects to this:
Creating the fields object with a property whose name is the value of variable rather than the literal name variable, and
Accessing the resulting field based on the value of the variable (rather than the literal name variable)
Dealing with #2 first because it's easier: In JavaScript, you can access a property on an object either using dot notation and a property name literal (obj.foo), or using brackets notation and a property name string* (obj["foo"]). In the latter case, the string can be the result of any expression, including a variable lookup. So if variable contains "foo", then obj[variable] will get or set the foo property on obj.
Back to #1: For now, you have to create the object you're going to pass as fields first and then assign the property value via brackets notation rather than in an object initializer:
var fields = {};
fields[variable] = 1;
If variable contains "foo", then fields[variable] = 1 sets the foo property on fields to 1.
So putting that all together:
var findData = function(variable){
var fields = {};
fields[variable] = 1;
return dailyLog.find({createdBy: Meteor.user().username}, {fields: fields}).fetch()[0][variable];
// Note ------------------------------------------------------------------------------^--------^
};
In the next version of JavaScript, ECMAScript6 (aka ES6), you'll be able to do #1 with a "computed property name" in the object initializer (and still retrieve it with brackets notation). Perhaps unsurprisingly, computed property names use...brackets!
// ES6 only!!
var findData = function(variable){
return dailyLog.find({createdBy: Meteor.user().username}, {fields: {[variable]: 1}}).fetch()[0].[variable];
// Note ------------------------------------------------------------^--------^ --- and ---------^--------^
};
* Side note: In ES6, brackets notation can be used with things called Symbols as well as strings. It's not relevant to your question, but I said "string" above, and soon that won't be true, so...

JavaScript property access using brackets

If I declare the following in my Chrome console:
var object = {0:0, 1:1}
I can call object[0] and object[1] and get their values. I can also call object["0"] and object["1"]. Next, if I declare:
var object = {"0":0, "1":1}
I can also make all four of the above calls. But if I declare:
var object = {a:0, 1:1}
I get a ReferenceError of "a is not defined" when I call object[a], but object["a"] returns 0, even though the property name in the declaration is not a string. I guess JavaScript thinks I'm calling a variable that doesn't exist in the first example. But why do calling object[0] and object["0"] both work? It seems that JavaScript is doing some kind of automatic conversion for numbers (presumably since they can't be variable names), but what are the rules for this? And is this behavior universal to other places it might come up or just to the bracket notation for objects?
When you use brackets, the expression inside the brackets is evaluated. What's the value of the expression
a
?? Well, if "a" isn't a declared variable, it's nonsense. When you use . notation, the identifier (and it must be an identifier) following the operator is treated as a string. It's just the way the language works.
The reason you're getting a ReferenceError for object[a] is because a literal a is a variable in javascript. "a" is a string containing the letter a.
You can use the dot notation object.a or the bracket notation with object["a"]
object.a; //=> 0
object["a"]; //=> 0
object[1]; //=> 1
object["1"]; //=> 1
Or you can use a variable for access
var x = "a";
object[x]; //=> 0
var y = 1;
object[y]; //=> 1
You are correct.
a there is a token which the engine assumes is a variable.
If you type "a" JS knows it's a string-primitive.
If you type 0, JS knows it's a number-primitive.
So on top of obj.a, obj["a"], obj[0], obj["0"], you can also say:
var a = 0;
obj[a]; // 0
Your app is exploding, because a hasn't been defined yet, and now you want to use it.
And yes, this is the expected behaviour.
What's inside of the brackets isn't seen as a "part" of the object -- it's a way of saying "give me the value of the object which is referenced by this key", where the key might be a number or string (or something that can be coerced into a string or number).
In the future, with maps and weakmaps, you would actually be able to use other objects/functions as keys as well.
var obj = new Map(),
func = function () { },
el = document.getElementById("myId");
obj[func] = 1;
obj[el] = 2;
Right now, these things technically work... ...but only because they're converted to their string values... ...so if you had two functions which were written the same (but technically two different objects), you would overwrite values, currently.
Inside of a map, they'd be treated as separate objects.
Using DOM elements is even worse, right now, as it might be useful to store hundreds of those and bind references to them, so that you don't have to keep looking for them... ...but for now, you need to make a unique ID number/key for each one, and store that, and remember the keys, and then create a child object to hold the data you want...
Whereas in the future, with maps, you could say:
var my_els = document.querySelector(".lots-of-els");
for (let el of my_els /* also the future */) {
console.log( my_map_of_data[el].info );
}

Can an Object object be coerced into an Array object?

Crockford writes in http://javascript.crockford.com/survey.html:
"There are two ways to make a new array:
var myArray = [];
var myArray = new Array();"
So I'm confused by these two lines in some AJAX code I am reading:
var obj={}; // obj is an Object object (i.e. a hash table)
obj[4] = 'x'; // now obj is suddenly an Array object via an integer key?
In JavaScript are an object and an array really just the same thing, but with a variant on the key type?
In other words, is this the same as in php where we can use either a name (string) or an integer for a hash key?
I've Googled for an answer on this but can't seem to nail down an article which discusses this issue.
One possibility that comes to mind is that perhaps the first line is syntactic lint because the 2nd line overwrites the previous definition of obj as it creates a new Array object.
it does not become an array, it is simply an Object with a '4' property, like this:
var obj = {
'4': 'x'
};
it is just converted to a string when used as a property like obj['4'] = 'x';
Everything but primitive datatypes is an object in JavaScript. Objects can have a properties and there are two ways to access object properties:
Dot notation, foo.bar, which you can use as long as the property name is a valid identifier.
Bracket notation, foo['bar'] which you have to use if the key is not a valid identifier [spec]. For example, if it is a number, or contains a space or you have a variable with the name.
Hence, bracket notation is not a characteristic of arrays and if you see it, it does not mean the value is an array. It is simple one of two ways of accessing properties.
The elements of an array are just properties with numeric keys. Arrays are built on top of objects and implement some additional methods which treat these numeric properties in a special way. For example the .length property is automatically updated when you add new elements. But ultimately they are just normal properties.
In your example you have a simple object. You have to access the property with obj[4] or obj['4'] because obj.4 is invalid since 4 is not a valid identifier (basically everything that you can use as variable name is a valid identifier. var 4 = 'foo'; is invalid).
And since arrays are just objects, if you could use numbers as identifiers, you were also able to access an element with arr.4.
As far as I know, no, an object can't be coerced into an array. But, it can look and act like an array, and that's what's happening here. Numbers, and anything else that can be coerced to a string, are perfectly valid property names for Javascript objects, so
obj[4] = 1;
obj['spam'] = 2;
are both valid ways of setting a property on the object. That doesn't make the object an array. An Array is a special class of object with specific methods (.slice(), .concat(), etc) and a length property that's kept up to date with the number of items in the array.
Yes
Javascript Array is very different from tradition array, you can think of it as object.
var array = [1,2,3] is equivalent to var object = {'0' : 1, '1' : 2, '2' : 3}
except array inherited from Array.prototype and object inherited from Object.prototype, where Array.prototype will contain method such as length.
Javascript is a loosely-typed, prototype-based language. Even primitive types like a boolean can be treated like an object (though you aren't going to get far). Almost everything in javascript is, at root, an object.
Understanding this, an array IS an object. You can arbitrarily add properties to any object:
var xml = new XMLHttpRequest();
xml[4] = 'x';
console.log(xml);
That object is still an instance of XMLHttpRequest. It now has a property labeled 4 with a value of x. You can treat anything like this -- even a function:
var test_func = function () {
alert('woah!');
}
test_func[4] = 'x';
console.log(test_func[4]);
The take-away here is that the obj[key] = value notation is NOT indicative of an "array" type, like it is in languages such as PHP. Rather, it is an alternate way to access properties of any object, and is equivalent to obj.key = value (you can't use obj.4 = 'x', though, that's invalid syntax). The other take-away is that any object in javascript can be modified or used in pretty much any way. You shouldn't misuse objects, but you can
Check it out here: http://jsfiddle.net/w2AqJ/
Documentation
Array on MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
Javascript "associative arrays" considered harmful by Andrew Dupont - http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/

how to get the value 'dynamically' from an associative array in javascript?

i am trying to get a value from a key stored on a string variable proyNombre, but whenever i call it via the common method "myAssociativeArray.MyKey", it gets the variable 'proyNombre' as the key, instead of getting its value and passing it as a key.
proyectos.each(function(index){
var proyNombre = this.value;
if(!(proyNombre in myArray)){ // whenever the variable is undefined, define it
myArray[proyNombre] = horas[index].value-0 + minutos[index].value/60;
}
else{
console.log(myArray.proyNombre); //This doesnt work, it tries to give me the value for the key 'proyNombre' instead of looking for the proyNombre variable
console.log(myArray.this.value); //doesnt work either
}
});
Try:
console.log(myArray[proyNombre]);
myArray is actually an object in javascript. You can access object properties with object.propertyName or, object['propertyName']. If your variable proyNombre contained the name of a property (which it does) you can use the second form, like I did above. object.proyNombre is invalid - proyNombre is a variable. You can't do for example:
var myObject = {};
myObject.test = 'test string';
var s = 'test';
console.log(myObject.s); // wrong!!
but you could then do:
console.log(myObject.test);
console.log(myObject['test']);
console.log(myObject[s]);
You need to use the same syntax you used to set the value:
console.log(myArray[proyNombre]);
Simply access the value with myArray[proyNombre].
You're doing it right in the assignment: myArray[proyNombre]. You can use the same method to retrieve the variable.
If you change:
console.log(myArray.proyNombre);
console.log(myArray.this.value);
to
console.log(myArray[proyNombre]);
console.log(myArray[this.value]);
You should get the same value (the value for the key represented by the variable proyNombre) logged twice.
It's true that Javascript doesn't have associative arrays but objects in Javascript can be treated like associative arrays when accessing their members.

Categories