Object and array with self referencing - javascript

I am very interested in understanding JavaScript behavior.
Object :
object = {object : window.object};
object = {object : window.object};
console.log(object === object); // true
console.log(object.object === object); // false
console.log(object.object === object.object); // true
console.log(object.object.object === object.object); // false
Array :
array = [window.array];
array = [window.array];
console.log(array === array); // true
console.log(array[0] === array); // false
console.log(array[0] === array[0]) // true
console.log(array[0][0] === array[0]) // false
Why
object.object.object === object.object
returns false ???

After the first assignment, you have the following:
object = { object: undefined }
The second assignment creates a new object, whose object property contains the previous value of window.object, and assigns this to object. So now you have:
object = { object: { object: undefined } }
So at this time, object.object is { object: undefined }, which is not the same as object.
Similar things happen with the array example.
If you want to create a self-referential object, you need to do:
object = {};
object.object = object;
This doesn't create a new object in the second assignment, it modifies the original object. Then you could do:
console.log(object.object.object.object === object); // true
For an array, it would be:
array = [];
array[0] = array;
console.log(array[0][0][0][0][0] === array); // true

There are two assignments to window.object. The first one creates a new object and assigns it to window.object. That one has a property called "object" whose value is undefined, because at the time the object literal is evaluated window.object is undefined.
The second assignment instantiates a new object. That one also has a property called "object", whose value is the object created in the first assignment.
Thus, window.object is not the same object as window.object.object.
The key is that in an assignment like this:
object = { object: window.object };
The value of the "object" property in the object literal is evaluated before the assignment takes place.

Let explain it line by line
object = {object : window.object};
//here object.object is undefined and object new object so object !== object.object
//lets obj1 = {object: undefined}
object = {object : window.object};
//here object is new instance of Object while object.object is equal to older object
//basically object != object.object
// obj2 = {object: obj1}
console.log(object === object); // true because same object obj2 == obj2
console.log(object.object === object); // false because two different object as obj1 != obj2
console.log(object.object === object.object); // true because same object obj1 == obj1
console.log(object.object.object === object.object); // false because undefined != obj1

Related

Create Function to Copy Properties From One Object to Another

I am trying to create a function that will copy all properties from a source object and paste them to a destination object. I want to create a deep copy, so I am not using object.assign().
Here is my code:
var obj1 = {
arr: ['a','b','c','d'], // >= 4 elements, all should be truthy
obj: {a:1,b:2,c:3,d:4}, // >= 4 values, all should be truthy
halfTruthyArr: [null,'b',null,'d'], // >= 4 elements, half should be falsy
halfTruthyObj: {a:1,b:null,c:3,d:null}, // >= 4 values, half should be falsy
string: 'This is a string.',
reverseString: function (string) {
if (typeof string === 'string') return string.split('').reverse().join('');
}
};
var obj2 = {}
function extend(destination, source) {
destination = JSON.parse(JSON.stringify(source))
}
extend(obj2,obj1)
console.log(obj2)
obj2 is not changed using the function. I understand the function uses pass by reference, which is why the object is not reassigned. Is there a way around this so that the object I pass in as a parameter is edited?
The reverseString method in obj1 does not get copied using JSON.stringify. Why is this?
if you are setting the value of an object or array inside of function it is Pass by Value. So you need to pass object by reference or try this
function extend(source) {
return JSON.parse(JSON.stringify(source))
}
var obj2=extend(obj1);
console.log("ext",obj2)
or pass by reference. In this case you are only changing the property inside of the object, not assigning a new value to the whole object
function extend(source, destination) {
destination.result = JSON.parse(JSON.stringify(source));
}
var destination = { result: {} };
extend(obj1, destination);
var obj2=destination.result;
console.log("ext", obj2);

When bar.constructor === Object is true?

On totpal
Below question is present.
What is a potential pitfall with using typeof bar === "object" to
determine if bar is an object? How can this pitfall be avoided?
Among its answers below statement is present
However, there’s one other alternative that returns false for nulls,
arrays, and functions, but true for objects:
console.log((bar !== null) && (bar.constructor === Object));
But when I try my code
var myObj =
{
name: "blah"
}
var bar =3;
console.log(typeof bar.constructor)
console.log(typeof myObj.constructor)
it gives output as function for both console.log
My question is what type of objects will have (bar.constructor === Object) as true?
"My question is what type of objects will have (bar.constructor === Object) as true?"
Generally, objects that inherit directly from Object.prototype instead of some intermediate constructor's .prototype or null.
Note that objects that do inherit directly from Object.prototype but shadow the .constructor property with its own value that doesn't point to Object will of course result in a false result of an equality comparison.
var o = {};
console.log(o.constructor === Object); // true
o.constructor = "foo";
console.log(o.constructor === Object); // false
Also, objects that do not inherit directly from Object.prototype, but rather from some other constructor that has a .prototype without a .constructor property will give a true result.
function Ctor() {}
var o = new Ctor();
console.log(o.constructor === Object); // false
delete Ctor.prototype.constructor;
console.log(o.constructor === Object); // true

'key' in vs object.key

Is there any difference between:
if('mykey' in obj){
}
and
if(obj.mykey){
}
?
Lets say you have
var obj = { mykey: false };
Then 'mykey' in obj will be true, while obj.mykey will be false. A very big difference.
The 'mykey' in obj expression will check if the object have a property or not. The obj.mykey expression will retrieve the value of the property and use that.
Also, if the object obj doesn't have a mykey property, then 'mykey' in obj will result in false while obj.mykey result in undefined.
if('mykey' in obj){
}
In the above case mkey is type of object say "Car" in "obj-Car" list
whereas
if(obj.mykey){
}
In the above you have mkey as property as "Engine" of object 'obj-Car'
if ('mykey' in obj) checks for existence of mykey property in obj.
if (obj.mykey) checks the value of mykey property in obj. The value could be undefined if the property doesn't exist, but it could also be null, false or empty string which will also evaluate to false.
In the first case, you are checking if mykey property exists in the object. In the second case, you are checking if mykey property of object is false, which includes being null, undefined, zero or even empty. So in the second case, if it exists, yet the value is zero, then the if statement won't get executed. In the first case it will, because it only checks if the property exists.
Example:
var obj = {"a": 1, "b": 0};
if ("b" in obj) { // gets executed }
if (obj.b) { // doesn't get executed }
let obj = {
mykey: true
}
if('mykey' in obj){
//checks if the object has this key
//true
}
if(obj.mykey){
//check if object key's value is 'true'
//true
}
whereas
let obj = {
mykey: false
}
if('mykey' in obj){
//checks if the object has this key
//true
}
if(obj.mykey){
//check if object key's value is 'true'
//false
}

What does Object(obj) === obj do?

different from obj != null;
I know that obj != null will detect anything that is allowed to have properties on it as null and undefined are the only two values which can not have properties.
How does this differ from
Object(obj) === obj;
Object(obj) === obj tests whether obj is an object or a primitive, failing also for strings, etc.
console.log(Object('foo') === 'foo'); // false
console.log(Object(true) === true); // false
console.log(Object(null) === null); // false
var obj = {};
console.log(Object(obj) === obj); // true
It's useful for determining if the value can be given and remember an assigned property.
While null and undefined outright error when attempting to use properties, which is why obj != null is still useful, no primitive values are able to hold onto properties.
var pri = 'foo';
pri.foo = 'bar'; // no error, but still...
console.log(pri.foo); // undefined
var box = Object(pri);
box.foo = 'bar';
console.log(box.foo); // 'bar'
Reference:
When obj is null or undefined, Object(obj) returns a new Object():
1) If value is null, undefined or not supplied, create and return a new Object object exactly as if the standard built-in Object constructor had been called with the same arguments (15.2.2.1).
And, primitive booleans, strings, and numbers are boxed into their object types via ToObject(), which are not equal to their primitive equivalents:
2) Return ToObject(value).
console.log(typeof 'foo' === 'string'); // true
console.log(typeof Object('foo') === 'object'); // true
console.log('foo' instanceof String); // false
console.log(Object('foo') instanceof String); // true
Identity (===. !==)
These operators behave identically to the equality operators except no type conversion is done, and the types must be the same to be considered equal.
http://www.c-point.com/javascript_tutorial/jsgrpComparison.htm
Nice Stack overflow link
Which equals operator (== vs ===) should be used in JavaScript comparisons?
Hope it helps

Why my object isn't equal Object? How to check if var is a Object?

I'm trying to detect is my variable is object.
I have that code:
var obj = {
'propA': 'a',
'propB': {
'underB': 'underBB',
'underB2': 'underBB2'
}
};
now when I checking: obj === Object I'm getting false even if when I type obj in console I see it's object:
Object {propA: "a", propB: Object}
DEMO
Questions:
How I can check if obj is a Object?
Why when I try compare my var and Object I'm getting false?
You can use:
if(typeof obj == 'object')
See here
This will also return true if obj is an array so sometimes its good to use instanceof to make sure its an object of the 'type' you want.
you can use instance of to determine type of an object.try this :
console.log(obj instanceof Object);
Besides, you are comparing object instance with a contractor(function) with === operator.this will always be false.

Categories

Resources