Accessing properties using for...in - javascript

I'm trying to access the properties of this object:
var obj = {hello: 1, world: 2};
This gives me back undefined:
function foo(a) {
for(property in a) {
console.log(a.property);
}
return "foo";
}
foo(obj);
This gives the intended result:
function bar(a) {
for(property in a) {
console.log(a[property]);
}
return "bar";
}
bar(obj);
Why does the call to foo not work, while the call to bar allows me to access the properties?

Because a.property is the same as a['property'], not a[property]. So you actually try to access the property "property".
Your second code snippet uses the variable property, the former uses the property property.

Related

Why object don't assigned the null

How explain behavior this function clear() ?
Why object a don't assigned the null ?
var a = {};
function clear(a) {
a.b = 2;
a = null;
}
clear(a);
console.log(a); // {b: 2}
console.log(a.b); // 2
When you create a variable in JavaScript, you are not working with the object itself. You are instead working with a reference to the object. Think of variables as signs that point to objects (in other languages like C, these references are appropriately called pointers).
Also, any arguments referenced inside of functions are their own, distinct references. Therefore, assigning these variables to something else while inside the function does not change (mutate) the object that they reference.
For example:
var someObject = {a: 1, b:2, c:3};
function doSomething(a) {
a = null;
}
doSomething(someObject);
console.log(someObject) // {a: 1, b:2, c:3}
The only thing that happened inside of the doSomething function was that a was set to point to null rather than someObject.
In your example, you have a global variable (variable defined outside of a function) called a, and a local function variable also called a. If you want the function to change the global a, you would have to either remove the argument from clear, or change the argument name and still reference a inside the clear function, like so:
var a = {};
function clear() {
a.b = 2;
a = null;
}
clear();
console.log(a); // null
console.log(a.b); // Uncaught TypeError: Cannot read property 'b' of null
or
var a = {};
function clear(b) {
a.b = 2;
a = null;
}
clear(a); // Note that it does not matter whether you pass a in or not
console.log(a); // null
console.log(a.b); // Uncaught TypeError: Cannot read property 'b' of null
When you are passing a to function clear, you pass the copy of the reference to object a. So executing a.b = 2; sets value b in object a.
But as I have mentioned a inside of clear function is just a copy of the reference, so setting it to null simply says that inside of the clear function parameter a points to null. it does not modify the original a object.

Declaring JavaScript Object property of a constructor object having arguments issue

I'm trying to create an object using constructor pattern and also define properties using Object.defineProperty.
function random (a,b,c) {
var sample = null;
this.a = a;
this.b = b;
if(b && c){
this.sample(b,c);
}
Object.defineProperty(random, 'sample', {
get: function(){
console.log(b);
}
});
};
var foo = new random(10,1,2);
This throws an error: Uncaught TypeError: object is not a function.
What am I doing wrong ? Please Help.
There are several issues:
You reference sample before it is defined
You define sample on the constructor (random), but it should be on this.
There was a closing parenthesis missing.
You call sample like a function, but you had not defined it as one. The function in defineProperty is the getter, not the method itself. If you want to code it like this, you need the getter to return your method.
Check this corrected code with comments:
function random (a,b,c) {
var sample = null;
this.a = a;
// First define, then call:
// Define on this, not on random:
Object.defineProperty(this, 'sample', {
get: function() {
// must return a function
return function (b) {
console.log(b);
};
}
}); // <-- missing bracket
// Moved after defineProperty:
if(b && c) {
this.sample(b,c); // note that you don't use the second argument
}
}
console.log(new random(1,2,3));

JavaScript syntax clarifying

For the following syntax
a = {
get p() {
alert(1)
}
};
alert(a.p);
It prompts me 1, than undefined.
For
a = {
set p(x) {
alert(x)
}
};
alert(a.p);
It prompts me undefined.
I do not totally understand the behaviour,
what does
a = {
get p() {
alert(1)
}
}
and
a = {
set p(x) {
alert(x)
}
};
mean?
There are two types of object properties: data properties and accessor properties. Accessor properties are accessed by getters and setters.
Your object a is intended as object with accessor property which called p.
Normally, such objects are declared in the following way:
a = {
_p: 'my value', // intended as private
get p() {
return this._p;
},
set p(x) {
this._p = x;
}
};
console.log(a.p); // gives 'my value'
a.p = 'new value';
console.log(a.p); // gives 'new value'
Another way is to use Object.defineProperty() method which lets you to set all needed properties attributes. Like this:
var a = {p: 'my value'};
Object.defineProperty(a, 'p', {
get: function() { return this.p; },
set: function(newValue) { this.p = newValue; },
enumerable: true,
configurable: true
});
because p() method returns nothing hence it returns undefined
if you do
a={get p(){alert(1); return 2;}};
alert(a.p);
it will alert 1 and then 2 since this p() method returned 2
{get p(){alert(1)}}
this is an object that has a getter p
when you use a.p it will use that getter to retrieve some value
so when you do alert(a.p); it first call the getter, so alert 1, then alert the returned value undefined.
[Edit] - You changed your original question so this answer doesn't cover everything.
p is a getter function - It is called whenever you access the p property. In your getter you have alert(1).
The getter function doesn't return anything. Thus, p is undefined. So the alert(a.p) alerts undefined.
Thus, your program does:
Get value of a.p: alert(a.p)
Calls p getter function. Which has alert(1)
p getter function returns nothing
Thus alert(a.p) alerts undefined

Constructor method can't access nested properties of a child object in a for loop

function myConstructor (arg) {
this.myName = arg;
this.totalNumber = 0;
this.foo = {
bar: {
someBoolean: false,
someNumber: 5
},
baz: {
someBoolean: false,
someNumber: 10
}
};
}
myConstructor.prototype.getNumber = function () {
console.log(this); //successfully returns the child object
for (var i in this.foo) {
//console log tests
console.log(this); //still returns the child object with all properties, including the myName 'whatever'
console.log(this.foo); //returns the 'foo' object with all nested properties
console.log(i); //returns 'bar' and 'baz', respectively
console.log(this.foo.hasOwnProperty(i)); //returns true
//where it all goes wrong
console.log(typeof(i)); //returns 'string'
console.log(this.foo.i); //returns undefined, even though 'this.foo' definitely has 'bar' and 'baz' properties
//what I'm trying to accomplish
/*
if (this.foo.i.hasOwnProperty('someBoolean') && this.foo.i.someBoolean === true) {
this.totalNumber += this.foo.i.someNumber;
} //returns 'TypeError: Cannot read property 'hasOwnProperty' of undefined
*/
}
return this.totalNumber;
};
var myChild = new myConstructor('whatever');
myChild.getNumber();
What I'm trying to accomplish is using a constructor to create a child. The having nested objects inside that child, with various properties that I will change later in my code. Then using a method of the constructor to access data within the nested objects of that child. Everything works until I get two-deep in nested objects.
I've tried passing every variable, object and property around with various "var this == that"s and "var prop == i"s and etc. Nothing I do seems to work.
foo has no property named i.
You want foo[i], to get the property with that name.
it should be console.log(this.foo[i])
As foo doen not contain "i" property.
Your confusion lies in the way that for-each/for-in loops are normally used in other programming languages such as Java, C#. Here's the difference:
// java
for(int x in list)
x = x+1;
// javascript
var x;
for(x in list)
list[x] = list[x] + 1;

Access The Prototype After Using Bind

I've noticed that when using bind on an object, you lose the ability to access the prototype.
function Foo(obj) {
this.fields = obj;
}
function Make(obj) {
return Foo.bind(Foo, obj);
}
var Test = Make({
name: 'Jeff'
});
console.log(Test.prototype);
Here's the same example not using bind:
function Foo(obj) {
this.fields = obj;
}
function Make(obj) {
return Foo;
}
var Test = Make({
name: 'Jeff'
});
console.log(Test.prototype);
Are there any ways around this?
So judging by the docs. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Bind ties a function to a specific object so that variables inside that object are always used. so when you're calling console.log in your example you're logging the prototype of the function Test. Not the object Test. So you get undefined.
In order to get the object you want try this:
console.log(new Test())

Categories

Resources